From 5203fc367a4057de0b53e6a56792669b23635157 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Mon, 2 Mar 2026 20:20:53 +0800 Subject: [PATCH 1/3] fix: fix memory leak by properly removing listener --- .../fix-event_release_2026-03-02-12-20.json | 10 ++++++++++ .../fix-event_release_2026-03-02-12-20.json | 10 ++++++++++ packages/vrender-animate/src/ticker/default-ticker.ts | 10 +++++++--- packages/vrender-components/src/scrollbar/scrollbar.ts | 2 +- 4 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 common/changes/@visactor/vrender-animate/fix-event_release_2026-03-02-12-20.json create mode 100644 common/changes/@visactor/vrender-components/fix-event_release_2026-03-02-12-20.json diff --git a/common/changes/@visactor/vrender-animate/fix-event_release_2026-03-02-12-20.json b/common/changes/@visactor/vrender-animate/fix-event_release_2026-03-02-12-20.json new file mode 100644 index 000000000..a62c0afc0 --- /dev/null +++ b/common/changes/@visactor/vrender-animate/fix-event_release_2026-03-02-12-20.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-animate", + "comment": "fix: fix memory leak by properly removing listener", + "type": "none" + } + ], + "packageName": "@visactor/vrender-animate" +} \ No newline at end of file diff --git a/common/changes/@visactor/vrender-components/fix-event_release_2026-03-02-12-20.json b/common/changes/@visactor/vrender-components/fix-event_release_2026-03-02-12-20.json new file mode 100644 index 000000000..57c432073 --- /dev/null +++ b/common/changes/@visactor/vrender-components/fix-event_release_2026-03-02-12-20.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-components", + "comment": "fix: fix memory leak by properly removing listener", + "type": "none" + } + ], + "packageName": "@visactor/vrender-components" +} \ No newline at end of file diff --git a/packages/vrender-animate/src/ticker/default-ticker.ts b/packages/vrender-animate/src/ticker/default-ticker.ts index 21908779e..be842f0f2 100644 --- a/packages/vrender-animate/src/ticker/default-ticker.ts +++ b/packages/vrender-animate/src/ticker/default-ticker.ts @@ -70,9 +70,7 @@ export class DefaultTicker extends EventEmitter implements ITicker { init(): void { this.interval = 16; this.status = STATUS.INITIAL; - application.global.hooks.onSetEnv.tap('graph-ticker', () => { - this.initHandler(false); - }); + application.global.hooks.onSetEnv.tap('graph-ticker', this._handleGraphTick); if (application.global.env) { this.initHandler(false); } @@ -221,6 +219,8 @@ export class DefaultTicker extends EventEmitter implements ITicker { this.tickerHandler?.release(); this.tickerHandler = null; this.lastFrameTime = -1; + + application.global.hooks.onSetEnv.unTap('graph-ticker', this._handleGraphTick); } protected checkSkip(delta: number): boolean { @@ -280,4 +280,8 @@ export class DefaultTicker extends EventEmitter implements ITicker { this.emit('tick', delta); }; + + protected _handleGraphTick = () => { + this.initHandler(false); + }; } diff --git a/packages/vrender-components/src/scrollbar/scrollbar.ts b/packages/vrender-components/src/scrollbar/scrollbar.ts index 23eb563a4..af6ad7db0 100644 --- a/packages/vrender-components/src/scrollbar/scrollbar.ts +++ b/packages/vrender-components/src/scrollbar/scrollbar.ts @@ -444,7 +444,7 @@ export class ScrollBar extends AbstractComponent> * 浏览器上的事件必须解绑,防止内存泄漏,场景树上的事件会自动解绑 */ super.release(all); - (vglobal.env === 'browser' ? vglobal : this.stage).addEventListener('touchmove', this._handleTouchMove, { + (vglobal.env === 'browser' ? vglobal : this.stage).removeEventListener('touchmove', this._handleTouchMove, { passive: false }); this._clearDragEvents(); From fb3e359dfbeefaa97952894dfa9003d1cb8287cd Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Tue, 3 Mar 2026 11:51:29 +0800 Subject: [PATCH 2/3] fix(stage): ensure proper cleanup by releasing ticker in dispose --- packages/vrender-core/src/core/stage.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vrender-core/src/core/stage.ts b/packages/vrender-core/src/core/stage.ts index 70e1d6efc..8b9fe10e2 100644 --- a/packages/vrender-core/src/core/stage.ts +++ b/packages/vrender-core/src/core/stage.ts @@ -1045,6 +1045,7 @@ export class Stage extends Group implements IStage { this.window.release(); this._ticker?.remTimeline(this?.timeline); this._ticker?.removeListener('tick', this.afterTickCb); + this._ticker?.release(); this.renderService.renderTreeRoots = []; } From 55b827017a6bcc39b253382473dd4b0db71bc655 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Tue, 3 Mar 2026 12:00:21 +0800 Subject: [PATCH 3/3] fix(stage): prevent releasing external ticker in stage cleanup --- packages/vrender-core/src/core/stage.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/vrender-core/src/core/stage.ts b/packages/vrender-core/src/core/stage.ts index 8b9fe10e2..396018041 100644 --- a/packages/vrender-core/src/core/stage.ts +++ b/packages/vrender-core/src/core/stage.ts @@ -1045,7 +1045,10 @@ export class Stage extends Group implements IStage { this.window.release(); this._ticker?.remTimeline(this?.timeline); this._ticker?.removeListener('tick', this.afterTickCb); - this._ticker?.release(); + if (!this.params.ticker) { + // release stage创建的ticker,避免release外部的ticker + this._ticker?.release(); + } this.renderService.renderTreeRoots = []; }