antvis / S2

⚡️ A practical visualization library for tabular analysis.
https://s2.antv.antgroup.com
MIT License
1.45k stars 192 forks source link

🐛透视表数据较多时,频繁滚动会导致栈溢出错误 #2771

Open tufaofu opened 2 months ago

tufaofu commented 2 months ago

🏷 Version

Package Version
@antv/s2 2.0.0-next.23
@antv/s2-react
@antv/s2-vue

Sheet Type

🖋 Description

当视表数据较多时,左右或者上下频繁滚动,会导致栈溢出错误。源码@antv/s2-v2.0.0-next.23分支,100w 数据 示例即可复现。

image

官网示例 100w条数据性能表现-透视表 也可复现。

image

🔗 Reproduce Link

https://s2.antv.antgroup.com/examples/case/performance-compare#pivot

🤔 Steps to Reproduce

电脑配置如下:

image

持续滚动60-120s左右就会报错

😊 Expected Behavior

😅 Current Behavior

💻 System information

Environment Info
System
Browser
lijinke666 commented 2 months ago

持续滚动60-120s左右就会报错

什么使用场景会一直滑动 1-2 分钟?

tufaofu commented 2 months ago

当图表数据量比较大,可能就会存在频繁滚动的情况

lijinke666 commented 2 months ago

近期看一下这个问题

lijinke666 commented 1 month ago

底层渲染引擎 G 的问题 https://github.com/antvis/G/issues/1712, 等待 G 修复

db-shuai commented 3 weeks ago

G 没人关注啊 这个好久了,有没有什么临时解决方案

wangnannanziyu commented 3 weeks ago

G 没人关注啊 这个好久了,有没有什么临时解决方案

把官方例子下下来,修改依赖中的g-lite包的源码,找到 Canvas.prototype.render,源代码如下: Canvas.prototype.render = function (frame) { var _this = this; this.dispatchEvent(beforeRenderEvent); var renderingService = this.getRenderingService(); renderingService.render(this.getConfig(), frame, function () { // trigger actual rerender event // @see https://github.com/antvis/G/issues/1268 _this.dispatchEvent(rerenderEvent); }); this.dispatchEvent(afterRenderEvent); };

修改后如下: try { var _this = this; this.dispatchEvent(beforeRenderEvent); var renderingService = this.getRenderingService(); renderingService.render(this.getConfig(), frame, function () { // trigger actual rerender event // @see https://github.com/antvis/G/issues/1268 _this.dispatchEvent(rerenderEvent); }); this.dispatchEvent(afterRenderEvent); } catch (error) { const renderer = this.getConfig().renderer this.getRenderingService().destroy(); this.context.renderingService = new RenderingService(runtime, this.context); this.initRenderingService(renderer) } 修改完后,重新构建,项目中引用你自己构建后的资源。

解决思路: catch 内存溢出的错误,然后销毁 render服务,重新生成一个。这样虽然还是会内存溢出,但是不影响使用。render这里的逻辑太长了,感觉底层设计有问题,这样可以临时解决