从一个性能优化的案例窥视html,svg,canvas各自适用的场景

2,663 阅读3分钟

什么样的功能?

这个功能是这样的,只需要将后端请求回来的数据渲染成有序排列的圆形,效果图大致如下:

image.png 想必聪明的各位读者一眼看到这个图就会想到利用各大可视化图形库来实现这个效果,备选的有d3,echarts,bizCharts等等类库,我们选择了d3,原因是d3提供了这种有序环形排列的算法,当然如果你的团队算法足够优秀,那可以直接自己写个算法,再结合div,svg,或者canvas就可以画出这样的图。

遇到了什么性能瓶颈?

如果使用svg来实现这样的功能,那你会发现,当数据量上千时,整个页面开始卡顿了起来,拖拽和放大的事件响应慢得不行,这时测试和产品经理就会提出不满:你们做的什么玩意,拖动不了了,页面很卡! 于是乎又到了令人愉快的找性能瓶颈环节,究竟是什么导致性能极致下降,进而页面卡顿?很明显,各位聪明的读者想必也是一眼就看了出来,就是dom节点太多导致的!没错,就是这样,dom节点多了,页面做各种交互的时候引起的重绘是相当耗费资源的,页面自然就卡了起来。

该怎么优化呢?

优化无非就这就几个方面,一个是减少dom,一个是去除代码中不必要的计算,最后是去除不必要的页面重渲染。关于这个功能,最重要的环节是减少dom。如何减少dom? 一种想法是当数据量很大时,只渲染前几百条数据,那就不会卡了,真棒!可产品经理不干了:所有数据全部都要展示!你们赶紧给我弄出来! 什么?有这么好弄?带着埋怨我们最终选择了canvas进行绘图优化,把这些节点缩减成一个canvas节点,满足了产品经理的需求。canvas的框架也有很多,这里推荐konva,上手容易,效果很棒。最后,用canvas实现了这个功能,性能也得到了极大的提升。

如何看html(div),svg,canvas适用的场景?

这里我们主要从绘图方面来谈一谈,如果对性能要求不太高数据量不太大的绘图需求,优先适用svg,div。比如图中这种坐标比较复杂的图,那就适用svg,如果排列简单,那直接用div+borderRadius也能实现圆的排列,不需要使用svg。如果数据量很大,还要支持各种事件响应,那最好还是选择canvas来做图形渲染。所以做功能之前最好有一个明确的区分,技术选型很重要,不然做好了项目,又回来返工改改改,这是很麻烦的事情!也做了很多无用功!浪费了很多资源!