diff --git a/common/changes/@visactor/vchart/fix-memory-leaks.json b/common/changes/@visactor/vchart/fix-memory-leaks.json new file mode 100644 index 0000000000..4186072c0f --- /dev/null +++ b/common/changes/@visactor/vchart/fix-memory-leaks.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "fix: Fix memory leaks in Player component and BaseComponent release logic.", + "type": "patch", + "packageName": "@visactor/vchart" + } + ], + "packageName": "@visactor/vchart", + "email": "visactor@bytedance.com" +} \ No newline at end of file diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 35ea7f4900..11cdbbb9d4 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -37,11 +37,11 @@ importers: specifier: 1.2.4-alpha.5 version: 1.2.4-alpha.5 '@visactor/vrender': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-kits': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vtable': specifier: 1.19.0-alpha.0 version: 1.19.0-alpha.0 @@ -203,11 +203,11 @@ importers: specifier: workspace:2.0.17 version: link:../vchart '@visactor/vrender-core': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-kits': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vutils': specifier: ~1.0.22 version: 1.0.22 @@ -294,11 +294,11 @@ importers: specifier: workspace:2.0.17 version: link:../vchart-extension '@visactor/vrender-core': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-kits': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vutils': specifier: ~1.0.22 version: 1.0.22 @@ -529,17 +529,17 @@ importers: specifier: ~1.0.22 version: 1.0.22 '@visactor/vrender-animate': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-components': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-core': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-kits': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vscale': specifier: ~1.0.22 version: 1.0.22 @@ -692,17 +692,17 @@ importers: specifier: ~1.0.22 version: 1.0.22 '@visactor/vrender-animate': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-components': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-core': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-kits': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vutils': specifier: ~1.0.22 version: 1.0.22 @@ -1260,14 +1260,14 @@ importers: specifier: workspace:2.0.17 version: link:../../packages/vchart '@visactor/vrender': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-core': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vrender-kits': - specifier: ~1.0.40 - version: 1.0.40 + specifier: ~1.0.41 + version: 1.0.41 '@visactor/vutils': specifier: ~1.0.22 version: 1.0.22 @@ -3073,29 +3073,29 @@ packages: '@visactor/vrender-animate@1.0.0-alpha.18': resolution: {integrity: sha512-9kTtvp1ef+1t+AtUiza6A7qBQP7SmvOu3/ILGrqs/HGdZVj1XGjbYvD/X/zwKJ3LEb7gGV5fa8x95e4czTvRSA==} - '@visactor/vrender-animate@1.0.40': - resolution: {integrity: sha512-/OT+xKwTdRa+bhTF28mQxl+9HsaIncNFGv00G3m2EHQT7Ls8SCDAyD46J36+bU3eYKz/+V+CzL2ApwI/zXP8/A==} + '@visactor/vrender-animate@1.0.41': + resolution: {integrity: sha512-kdMoIh7OEo6z4rZfnJHX7d+izBhGVWq6MR22uppk0LPilfdBd/1hSNAEKO6C9JWAy5uROGFpEkh+kk+ar/zSZg==} '@visactor/vrender-components@1.0.0-alpha.18': resolution: {integrity: sha512-7Euq+ZfswL74n2pgkaqZSsPxoSa5SPIGyXatN1eUrdzM2Z0kX6U0RcJg01fctvRs4op6WhcecRLqGvnHcBeb9Q==} - '@visactor/vrender-components@1.0.40': - resolution: {integrity: sha512-+mooyFfpAaAjhBDN5XHKz1SH0vHe3IjabLJQWYwDZGvpPHieVIlZstkTIRMH63pJek0ViIZLHcxpf/i/qli+sw==} + '@visactor/vrender-components@1.0.41': + resolution: {integrity: sha512-B7iXJE1TdkYapPZN6DNxoaErY4FzGf5AbcbG/z6Q0hnzO4Iw1hKdtlTGOIYA1+JXhehDWcyy+D0bnoNQNf+rgw==} '@visactor/vrender-core@1.0.0-alpha.18': resolution: {integrity: sha512-0ihtNvCyNkOsWPFgRqowHzq0IcQgS2Wl/nPpKbVtxWKveenwlhA+ZKoQvam6VJyBY7jeNe1pROy0mJMDyVAJQw==} - '@visactor/vrender-core@1.0.40': - resolution: {integrity: sha512-VNfxYGvNS2k1v2/+H0y9jIxjsFjgy3ieFGTDYz+o1rES2RY4wQIr6xJtdEkzXg6Foavp1gJj4fSf/wl2idEuTA==} + '@visactor/vrender-core@1.0.41': + resolution: {integrity: sha512-P7YVUJ45vwqPA460W6JJjg201ThvxBrjEgTBJ4tHKaHZPP/nVyF8rPyUOCL8QesEFDB+R0e/sUJUVs+ckHhd2w==} '@visactor/vrender-kits@1.0.0-alpha.18': resolution: {integrity: sha512-Tvolkq+4G8qiPFZo0Aj8M//Yr6jR2h8FNkFEyWM9gbQbEiTkjpmHAJOYnoSsaPtPrcMSlG4EhJSFDk6ymANHVg==} - '@visactor/vrender-kits@1.0.40': - resolution: {integrity: sha512-tMD2C4vQd5kN2WyDIkel4tId1NYGclKM1exIsJY51rgOjfJsjpRzC5WPe6KYqoIcDO5xDarX8TY4dkTR9S0l6w==} + '@visactor/vrender-kits@1.0.41': + resolution: {integrity: sha512-ffJlKkNseOsnRjvBmxKxQ9dsQXu+K288NFCtB0ZZ2N/mtcTsZUlH5SDCcsAvDhPGEvJ22Ye4MFKcXSEDctpGzA==} - '@visactor/vrender@1.0.40': - resolution: {integrity: sha512-jgplV+ZSsbcWrOc0v4+IbSEwXy9B7xrfMYKYlcPt2U+W6g/kmguXoAnMmq07Qj3IVuUoJDdmyyaNesrUv0ENvQ==} + '@visactor/vrender@1.0.41': + resolution: {integrity: sha512-FUpN89qavMUZBVobiF9OmvGgJv3t8mBy2FZyTaybgTl2msqjQzVF2CnlxjKzvv3daLusniok3T+bdo0AoQGzLw==} '@visactor/vscale@0.18.18': resolution: {integrity: sha512-iRG4kv+5Fv4KX3AxEfV95XU3I6OmF0QizyAhqHxKa7L1MaT+MRvDDk5zHWf1E8gialLbL2xDe3GnT6g/4u5jhA==} @@ -6565,7 +6565,7 @@ packages: glob@6.0.4: resolution: {integrity: sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} @@ -15026,9 +15026,9 @@ snapshots: '@visactor/vrender-core': 1.0.0-alpha.18 '@visactor/vutils': 1.0.4 - '@visactor/vrender-animate@1.0.40': + '@visactor/vrender-animate@1.0.41': dependencies: - '@visactor/vrender-core': 1.0.40 + '@visactor/vrender-core': 1.0.41 '@visactor/vutils': 1.0.22 '@visactor/vrender-components@1.0.0-alpha.18': @@ -15039,11 +15039,11 @@ snapshots: '@visactor/vscale': 1.0.4 '@visactor/vutils': 1.0.4 - '@visactor/vrender-components@1.0.40': + '@visactor/vrender-components@1.0.41': dependencies: - '@visactor/vrender-animate': 1.0.40 - '@visactor/vrender-core': 1.0.40 - '@visactor/vrender-kits': 1.0.40 + '@visactor/vrender-animate': 1.0.41 + '@visactor/vrender-core': 1.0.41 + '@visactor/vrender-kits': 1.0.41 '@visactor/vscale': 1.0.22 '@visactor/vutils': 1.0.22 @@ -15052,7 +15052,7 @@ snapshots: '@visactor/vutils': 1.0.4 color-convert: 2.0.1 - '@visactor/vrender-core@1.0.40': + '@visactor/vrender-core@1.0.41': dependencies: '@visactor/vutils': 1.0.22 color-convert: 2.0.1 @@ -15066,21 +15066,21 @@ snapshots: lottie-web: 5.13.0 roughjs: 4.5.2 - '@visactor/vrender-kits@1.0.40': + '@visactor/vrender-kits@1.0.41': dependencies: '@resvg/resvg-js': 2.4.1 - '@visactor/vrender-core': 1.0.40 + '@visactor/vrender-core': 1.0.41 '@visactor/vutils': 1.0.22 gifuct-js: 2.1.2 lottie-web: 5.13.0 roughjs: 4.6.6 - '@visactor/vrender@1.0.40': + '@visactor/vrender@1.0.41': dependencies: - '@visactor/vrender-animate': 1.0.40 - '@visactor/vrender-components': 1.0.40 - '@visactor/vrender-core': 1.0.40 - '@visactor/vrender-kits': 1.0.40 + '@visactor/vrender-animate': 1.0.41 + '@visactor/vrender-components': 1.0.41 + '@visactor/vrender-core': 1.0.41 + '@visactor/vrender-kits': 1.0.41 '@visactor/vscale@0.18.18': dependencies: diff --git a/docs/package.json b/docs/package.json index 9d22e10416..6bd2a8bf50 100644 --- a/docs/package.json +++ b/docs/package.json @@ -19,8 +19,8 @@ "@visactor/vchart-theme": "~1.6.6", "@visactor/vmind": "1.2.4-alpha.5", "@visactor/vutils": "~1.0.22", - "@visactor/vrender": "~1.0.40", - "@visactor/vrender-kits": "~1.0.40", + "@visactor/vrender": "~1.0.41", + "@visactor/vrender-kits": "~1.0.41", "@visactor/vtable": "1.19.0-alpha.0", "@visactor/vtable-editors": "1.19.0-alpha.0", "@visactor/vtable-gantt": "1.19.0-alpha.0", @@ -58,4 +58,4 @@ "react-device-detect": "^2.2.2", "minimist": "1.2.8" } -} +} \ No newline at end of file diff --git a/packages/openinula-vchart/package.json b/packages/openinula-vchart/package.json index 02d62a8669..83c08dbd41 100644 --- a/packages/openinula-vchart/package.json +++ b/packages/openinula-vchart/package.json @@ -30,8 +30,8 @@ "dependencies": { "@visactor/vchart": "workspace:2.0.17", "@visactor/vutils": "~1.0.22", - "@visactor/vrender-core": "~1.0.40", - "@visactor/vrender-kits": "~1.0.40", + "@visactor/vrender-core": "~1.0.41", + "@visactor/vrender-kits": "~1.0.41", "react-is": "^18.2.0" }, "devDependencies": { @@ -78,4 +78,4 @@ "access": "public", "registry": "https://registry.npmjs.org/" } -} +} \ No newline at end of file diff --git a/packages/react-vchart/package.json b/packages/react-vchart/package.json index 6df82a0308..322230c638 100644 --- a/packages/react-vchart/package.json +++ b/packages/react-vchart/package.json @@ -31,8 +31,8 @@ "@visactor/vchart": "workspace:2.0.17", "@visactor/vchart-extension": "workspace:2.0.17", "@visactor/vutils": "~1.0.22", - "@visactor/vrender-core": "~1.0.40", - "@visactor/vrender-kits": "~1.0.40", + "@visactor/vrender-core": "~1.0.41", + "@visactor/vrender-kits": "~1.0.41", "react-is": "^18.2.0" }, "devDependencies": { @@ -83,4 +83,4 @@ "access": "public", "registry": "https://registry.npmjs.org/" } -} +} \ No newline at end of file diff --git a/packages/vchart-extension/__tests__/runtime/browser/test-page/ranking-list.ts b/packages/vchart-extension/__tests__/runtime/browser/test-page/ranking-list.ts index c6e2540ea2..6947b08790 100644 --- a/packages/vchart-extension/__tests__/runtime/browser/test-page/ranking-list.ts +++ b/packages/vchart-extension/__tests__/runtime/browser/test-page/ranking-list.ts @@ -250,7 +250,7 @@ const spec = { }, // animation: false, customTransformSpec: spec => { - console.log('spec----', spec); + // console.log('spec----', spec); spec.axes[0].paddingOuter = 0.7; } }; diff --git a/packages/vchart-extension/package.json b/packages/vchart-extension/package.json index a35e0f1761..e5aec6e063 100644 --- a/packages/vchart-extension/package.json +++ b/packages/vchart-extension/package.json @@ -21,10 +21,10 @@ "start": "ts-node __tests__/runtime/browser/scripts/initVite.ts && vite serve __tests__/runtime/browser" }, "dependencies": { - "@visactor/vrender-core": "~1.0.40", - "@visactor/vrender-kits": "~1.0.40", - "@visactor/vrender-components": "~1.0.40", - "@visactor/vrender-animate": "~1.0.40", + "@visactor/vrender-core": "~1.0.41", + "@visactor/vrender-kits": "~1.0.41", + "@visactor/vrender-components": "~1.0.41", + "@visactor/vrender-animate": "~1.0.41", "@visactor/vchart": "workspace:2.0.17", "@visactor/vutils": "~1.0.22", "@visactor/vdataset": "~1.0.22", @@ -66,4 +66,4 @@ "directory": "packages/vchart-extension" }, "license": "MIT" -} +} \ No newline at end of file diff --git a/packages/vchart/__tests__/runtime/browser/test-page/radar.ts b/packages/vchart/__tests__/runtime/browser/test-page/radar.ts index f1d2d3621a..bd604be4eb 100644 --- a/packages/vchart/__tests__/runtime/browser/test-page/radar.ts +++ b/packages/vchart/__tests__/runtime/browser/test-page/radar.ts @@ -2,7 +2,7 @@ import { isMobile } from 'react-device-detect'; import type { IRadarChartSpec } from '../../../../src/index'; import { VChart } from '../../../../src/index'; -const run = () => { +const run = async () => { const mockData: any[] = []; const types = ['A', 'B', 'C']; @@ -69,7 +69,47 @@ const run = () => { cs.renderAsync().then(() => { console.timeEnd('renderTime'); }); + + const c = document.createElement('button'); + c.innerHTML = 'release'; + c.style.marginRight = '5px'; + c.style.marginTop = '5px'; + function releaseChart() { + cs.release(); + // cs.destroy(); + } + c.onclick = releaseChart; + document?.getElementsByTagName('body')[0].appendChild(c); + + const d = document.createElement('button'); + d.innerHTML = 'reRender'; + d.style.marginRight = '5px'; + d.style.marginTop = '5px'; + function reRenderChart() { + const cs = new VChart(spec, { + dom: document.getElementById('chart') as HTMLElement, + //theme: 'dark', + onError: err => { + console.error(err); + } + }); + console.time('renderTime'); + + cs.renderSync(); + window['vchart'] = cs; + } + d.onclick = reRenderChart; + document?.getElementsByTagName('body')[0].appendChild(d); + window['vchart'] = cs; console.log(cs); + + for (let i = 0; i < 1000; i++) { + await new Promise(resolve => setTimeout(resolve, 100)); + window['vchart'].release(); + + await new Promise(resolve => setTimeout(resolve, 100)); + reRenderChart(); + } }; run(); diff --git a/packages/vchart/package.json b/packages/vchart/package.json index 65594f2b04..c3514d441d 100644 --- a/packages/vchart/package.json +++ b/packages/vchart/package.json @@ -122,14 +122,14 @@ "@visactor/vdataset": "~1.0.22", "@visactor/vscale": "~1.0.22", "@visactor/vlayouts": "~1.0.22", - "@visactor/vrender-core": "~1.0.40", - "@visactor/vrender-kits": "~1.0.40", - "@visactor/vrender-components": "~1.0.40", - "@visactor/vrender-animate": "~1.0.40", + "@visactor/vrender-core": "~1.0.41", + "@visactor/vrender-kits": "~1.0.41", + "@visactor/vrender-components": "~1.0.41", + "@visactor/vrender-animate": "~1.0.41", "@visactor/vutils-extension": "workspace:2.0.17" }, "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" } -} +} \ No newline at end of file diff --git a/packages/vchart/src/component/base/base-component.ts b/packages/vchart/src/component/base/base-component.ts index f234ae3287..e799ea8c3d 100644 --- a/packages/vchart/src/component/base/base-component.ts +++ b/packages/vchart/src/component/base/base-component.ts @@ -104,6 +104,7 @@ export class BaseComponent extends La if (components && components.length) { components.forEach(c => { if (c) { + c.release(true); this.getContainer()?.removeChild(c as unknown as INode); c = null; } diff --git a/packages/vchart/src/component/player/player.ts b/packages/vchart/src/component/player/player.ts index deb7584066..ec9b7fc1fa 100644 --- a/packages/vchart/src/component/player/player.ts +++ b/packages/vchart/src/component/player/player.ts @@ -319,7 +319,12 @@ export class Player extends BaseComponent implements IComponent { } }); } - + autoPlayCallback = () => { + if (this._spec?.auto) { + this._playerComponent.pause(); + this._playerComponent.play(); + } + }; /** * 事件 */ @@ -328,12 +333,9 @@ export class Player extends BaseComponent implements IComponent { return; } // 自动播放 - this._option.globalInstance.on(ChartEvent.rendered, () => { - if (this._spec?.auto) { - this._playerComponent.pause(); - this._playerComponent.play(); - } - }); + this._option.globalInstance.off(ChartEvent.rendered, this.autoPlayCallback); + // 自动播放 + this._option.globalInstance.on(ChartEvent.rendered, this.autoPlayCallback); // 循环播放 与 交替方向 this._playerComponent.addEventListener(PlayerEventEnum.end, () => { @@ -417,6 +419,10 @@ export class Player extends BaseComponent implements IComponent { }); }); }; + release(): void { + // 自动播放 + this._option.globalInstance.off(ChartEvent.rendered, this.autoPlayCallback); + } } export const registerPlayer = () => { diff --git a/packages/vchart/src/core/vchart.ts b/packages/vchart/src/core/vchart.ts index b3081dd4af..b337bf670d 100644 --- a/packages/vchart/src/core/vchart.ts +++ b/packages/vchart/src/core/vchart.ts @@ -453,7 +453,7 @@ export class VChart implements IVChart { // 设置全局字体 this._setFontFamilyTheme(this.getTheme('fontFamily') as string); this._initDataSet(this._option.dataSet); - this._autoSize = isTrueBrowseEnv ? (spec.autoFit ?? this._option.autoFit ?? true) : false; + this._autoSize = isTrueBrowseEnv ? spec.autoFit ?? this._option.autoFit ?? true : false; this._bindResizeEvent(); this._bindViewEvent(); this._initChartPlugin(); @@ -1520,7 +1520,7 @@ export class VChart implements IVChart { } const lasAutoSize = this._autoSize; - this._autoSize = isTrueBrowser(this._option.mode) ? (this._spec.autoFit ?? this._option.autoFit ?? true) : false; + this._autoSize = isTrueBrowser(this._option.mode) ? this._spec.autoFit ?? this._option.autoFit ?? true : false; if (this._autoSize !== lasAutoSize) { resize = true; } diff --git a/specs/fix-memory-leaks/plan.md b/specs/fix-memory-leaks/plan.md new file mode 100644 index 0000000000..8a6f749cd7 --- /dev/null +++ b/specs/fix-memory-leaks/plan.md @@ -0,0 +1,11 @@ +## Summary +Fix memory leaks in Player component and BaseComponent release logic. + +## Technical Context +- Update `@visactor/vrender` related packages to `1.0.41`. +- In `BaseComponent`, call `release(true)` when removing child components. +- In `Player`, properly unbind `autoPlayCallback` event listener on release. +- Fix `_autoSize` logic in `VChart`. + +### Source Code (repository root) +- packages/vchart/ diff --git a/tools/story-player/package.json b/tools/story-player/package.json index 2a5205cfde..a7fe0746a3 100644 --- a/tools/story-player/package.json +++ b/tools/story-player/package.json @@ -56,10 +56,10 @@ "vite": "3.2.6" }, "dependencies": { - "@visactor/vrender-core": "~1.0.40", - "@visactor/vrender-kits": "~1.0.40", + "@visactor/vrender-core": "~1.0.41", + "@visactor/vrender-kits": "~1.0.41", "@visactor/vchart": "workspace:2.0.17", - "@visactor/vrender": "~1.0.40", + "@visactor/vrender": "~1.0.41", "@visactor/vutils": "~1.0.22" } -} +} \ No newline at end of file