多个Highcharts实例JS更新过慢 如何提升更新性能
核心结论
mybankjson对应的JSON文件体积不是卡顿的核心原因。你单张图表仅10-12条数据,40张图表总数据量通常不超过100KB,只要JSON已经提前加载到内存中,浏览器解析数据的耗时仅几毫秒,完全可以忽略。
卡顿的核心原因是更新逻辑触发了大量重复重绘,叠加动画开销,造成了冗余的DOM操作和渲染计算:
- 调用
chart.update()直接替换series配置时,Highcharts会销毁原有series实例、重建新实例,每次调用默认触发1次全图表重绘 - 逐个调用
setData()、setTitle()时,默认每调用1次方法就触发1次重绘,单张图表就要触发4次重绘,40张图表累计触发上百次重绘,你测到的单张平均0.5秒耗时基本都来自重复渲染。
可落地的优化手段
第一优先级:关闭更新过程的自动重绘,所有修改完成后统一重绘
所有更新操作都传入redraw: false参数,禁止单次操作触发渲染,等单张图表的所有series、标题都更新完成后,再统一调用一次redraw()。追求极致性能的话,可以等所有40张图表的数据全部赋值完成后,再批量触发所有图表的重绘,同时直接关闭切换时的动画效果——动画对多图表批量更新场景没有实际价值,只会徒增计算开销。
参考实现代码:// 全局关闭图表更新动画,也可在单图表初始化时单独配置 Highcharts.setOptions({ chart: { animation: false } }); // 遍历所有图表更新数据,全程不触发重绘 allCharts.forEach(chart => { chart.series[0].setData(mybankjson.data.spr_t_tva, false); chart.series[1].setData(mybankjson.data.enf_t_tva, false); chart.series[2].setData(mybankjson.data.hogares_t_tva, false); chart.setTitle({ text: `Tasas de variación interanual del crédito. SPR<br>(${ecode}-${anombre})` }, false); }); // 所有数据更新完成后,统一执行一次重绘 allCharts.forEach(chart => chart.redraw());仅这一项优化通常就能把总更新耗时降到原来的1/5-1/10。
第二优先级:按需更新可视区域内的图表
如果40张图表是长页面滚动布局,用户同一时间只能看到视口内的3-5张图表,不需要在combobox切换时一次性更新所有图表。可以监听页面滚动事件,仅更新滚动到可视区域内的图表,非可视区域的图表等用户快滚到对应位置时再触发更新,首屏更新的耗时会直接降到几十毫秒级别,完全感知不到卡顿。第三优先级:减少不必要的渲染开销
检查图表配置,关闭非必要的渲染项:比如series阴影、默认全量显示的数据标签、实时跟随鼠标的十字准星、不必要的边框圆角等效果,这些配置单张图开销不大,但40张图叠加后会累计出明显的渲染耗时。
另外优先用setData()更新已有series的数据,不要用chart.update()整体替换series配置,后者会销毁重建series实例,额外增加实例初始化的开销。
内容的提问来源于stack exchange,提问作者Javi Delgado

