v5/v6 版本滚动性能下降明显
问题描述
S2 1.x 平均滚动帧率接近 60 fps
"@antv/g-canvas": "^0.5.12"
S2 2.x 平均滚动帧率只有 20+ fps, long task 很多, 且滚动一段时间后会出现 G 内部的堆栈溢出 (初步看起来应该不是 S2 导致的): https://github.com/antvis/S2/issues/2771
"@antv/g": "^6.0.6",
"@antv/g-canvas": "^2.0.7",
"@antv/g-lite": "^2.0.5"
滚动相关的代码如下, 和 1.x 基本一致:
https://github.com/antvis/S2/blob/f8e00e535ceae093ef34e7de6cfe4a8cfc05f985/packages/s2-core/src/facet/base-facet.ts#L1331-L1433
G 这里没看到有 cancelRequestFrame 的操作, 不太懂这块实现, 且不管有没有滚动 (appendChild), 一直在执行 (看回复是脏检查 https://github.com/antvis/G/issues/1626 ? )
复现链接和步骤
https://s2.antv.antgroup.com/examples/case/performance-compare/#pivot
使用触摸板 水平/垂直滚动 10s 左右即可复现
期望
希望高优处理下
- 滚动帧率不要太低, 感到肉眼卡顿
- 解决频繁滚动后导致堆栈溢出的问题 (对于 G 来说应该就是频繁添加 大量 group 后, 再大量移除 group).
请问有没有什么进展或结论
什么时候能修复啊 !!!!!
同问,有没有进展?
+10086,有没有进展?
没进展了吗?维护的大佬隐居了嘛
请问有没有什么进展或结论呢? 可以先回复一下么?或者有什么计划么?
性能优化是关注的重点,但是短期内应该暂时解决不了,如果有更多技术细节可以持续反馈,会一直关注的
性能优化是关注的重点,但是短期内应该暂时解决不了,如果有更多技术细节可以持续反馈,会一直关注的
@wang1212 这块能提供一些问题可能发生的方向吗?是因为什么短期内解决不了呢?如果有可能的话看看能不能说一下,让社区的同学们一起尝试解决下。
我也复现了该问题,但是设置enableCulling: false,就可以避免Maximum的问题,性能上依然存在下降 "@antv/g": "^5.18.25", "@antv/g-canvas": "^1.11.27", "@antv/g-components": "^1.9.22",
有没有办法临时解决,目前我也遇到了。报错一样的
"@antv/event-emitter": "^0.1.3", "@antv/g": "^6.0.12", "@antv/g-canvas": "^2.0.10", "@antv/g-lite": "^2.0.8",
有没有办法临时解决,目前我也遇到了。报错一样的
"@antv/event-emitter": "^0.1.3", "@antv/g": "^6.0.12", "@antv/g-canvas": "^2.0.10", "@antv/g-lite": "^2.0.8",
试试升级下 G 相关包的版本
目前,根据性能数据分析,在 G 的核心渲染流程中,对象的渲染为串行独立渲染,会频繁触发 context.save()/context.restore(),并且每一个对象的渲染都会执行 context.fill()/context.stroke(),在数据量级比较大时,对性能产生的明显的影响(每帧耗时增加 ~40%),正在进行针对性的优化
大佬们, 这个有进度吗?
大佬们, 这个有进度吗?
目前,已经结合 G 和 S2 持续做了一些优化,有一定的性能提升,针对 G 的优化后续可以关注 #1967
S2 的性能数据是不是可以披露一下? @Alexzjt
综合2025上半年的性能优化手段,在相同测试设备环境(19款 MacBookPro Intel 16GB)下,S2交叉表百万数据滚动FPS可以稳定到34左右,对比性能优化前15~20FPS,基本实现了性能翻倍。下半年继续努力,争取达到50FPS。内存泄漏问题已清零。
@lijinke666 Hello! Here is an automated response to your question:
感谢您的详细反馈和复现信息!我们已关注到 G v5/v6 在与 S2 2.x 配合滚动场景下出现的帧率下降和堆栈溢出问题。针对您的疑问,现做如下分析和建议:
1️⃣ 滚动性能优化建议
- 脏矩形渲染优化:G v5/v6 默认启用“脏矩形”机制,即只重绘发生变化的区域,理论上能显著提升性能。但如果滚动、操作频繁导致脏区域合并接近全画布,则优化效果会减弱。建议排查是否有过多 group 节点频繁变化、合并导致脏区域过大。
- 合理使用剔除功能(如 WebGL/WebGPU):如果使用 WebGL 渲染,可确保开启
cullFace背面剔除,避免渲染不可见元素。 - 事件监听:可结合
AFTER_RENDER事件和性能统计工具,实时监控帧率和渲染区域,定位性能瓶颈。
参考代码:
canvas.addEventListener('afterrender', () => {
stats.update(); // 实时统计帧率等性能数据
});
- 调试脏区:可用
CanvasEvent.DIRTY_RECTANGLE事件可视化脏矩形,快速定位重绘区域。
2️⃣ 频繁 group 操作导致堆栈溢出的建议
- 合理管理 group 层级与数量:频繁
appendChild/removeChild大量 group,容易导致堆栈溢出或内存泄露。建议:- 优先复用 group 节点,而非反复创建/销毁。
- 批量操作时,尽量合并为单次操作,减少递归遍历和节点重排。
- 使用
removeChild(group, true)可彻底销毁避免残留。
关键 API:
group.appendChild(child); // 添加
group.removeChild(child, true); // 移除并销毁
group.hasChildNodes(); // 检查是否有子节点
- 场景图层级过深时建议拆分或优化节点结构,避免过度嵌套引起递归溢出。
3️⃣ 关于 G 的脏检查机制
- 工作原理:G 会定期检测节点属性或层级变化(脏检查),并触发重绘。默认所有操作(即使无滚动)都会定期检查并可能触发渲染,以确保 UI 实时更新。
- 性能调优:
- 可以通过 renderer 的配置项关闭自动渲染或脏检查,改为手动控制渲染周期,缓解频繁重绘带来的性能压力。
- 配置示例:
const renderer = new CanvasRenderer({ enableAutoRendering: false, // 关闭自动渲染 enableDirtyCheck: true, // 启用脏检查(建议保留) }); - 若确实发现“无滚动时也频繁执行”,建议排查是否有其他 UI 组件或插件在不断修改属性,或者反馈更多详细的场景代码,便于进一步定位。
🔗 复现与协作
- 您提供的 S2 代码与 G 集成基本无差异,建议先参考上面优化点进一步排查,并可通过 脏矩形可视化 辅助调试。
- 如有进一步堆栈溢出定位信息(如具体异常堆栈),欢迎补充,我们会持续跟进。
✅ 后续计划
- 优先跟进堆栈溢出问题,将在近期修复和优化 group 管理相关逻辑。
- 性能优化方案讨论,欢迎提供更多性能数据、具体场景代码,协助定位瓶颈。
- 如需临时缓解,建议优先关闭自动渲染、合并批量 group 操作,并开启脏矩形调试辅助定位。
再次感谢您的反馈!如有进一步问题,欢迎继续补充,我们会持续跟进和优化。
This is an automated response generated by AI. If you have any questions, our team will follow up as soon as possible.
