前端大量数据渲染指南探索

5,710 阅读4分钟

前言

大数据公司绘图很容易碰到上万、上十万、上百万的数据,当前端开发人员面对成千上万条记录要显示的时候,我们该怎么处理?下面探索一下可行性

SVG篇(请参考代码数据量调式)

1. 普通数据渲染

示例:codepen.io/arcsin1/pen…

缺点:

  1. js执行是单线程的,这么大数据(上几十万或者百万)肯定崩溃了
2. SetTimeout分组分时渲染

示例:codepen.io/arcsin1/pen…

优点:

  1. 不会因为大量数据(上几十万)导致整个页面白屏,会正常渲染页面
  2. 利用setTimeout函数开启一个新的执行线程(异步),防止主线程因渲染大量数据导致阻塞。
  3. 当然上面说法是个假的,setTimeout并不算真正的多线程, 但是为了方便表达,便借用了线程一词

缺点:

  1. js执行是单线程的,阻塞js运行,数据量大了到后面过程还是会卡死,页面半天没反应啊(setTimeout无法预测时间执行)

  2. js虽然通过setTimeout执行了分片,浏览器渲染进程没执行完还是导致卡顿

3. RequestAnimationFrame分组分时优化渲染

示例: codepen.io/arcsin1/pen…

优点:

  1. 无需计算回调时间,动画的流畅性更有保障。

    • 无论是setTimeout或者是setInterval都需要指明浏览器回调函数的时间。尽管设置了1000/60的回调时间,也就是每秒60帧的动画,但是并不能保证浏览器的真实回调时间,可能会造成动画卡顿。
    • requestAnimationFrame 不需要设置回调时间,跟着浏览器的重绘的钩子走。这种做法更加高效,不会失帧或者卡顿,更大程度的保证了动画的流畅性。
  2. 性能优秀,占用更少内存。

    • 对隐藏或者不可见元素的动画,requestAnimationFrame 不会进行重绘或者是回流,意味着占用的内存更少,性能更好
  3. requestAnimationFrame会节省资源,运行浏览器时会自动优化调用,在浏览器tab页面不是激活状态下,会自动暂停执行,有效节省CPU的开销

缺点:

  1. 虽然比setTimeout好很多,但是到后面数据累积越多 还是越卡 执行就越久
4. MutationObserver监听dom元素分组分时渲染

示例:codepen.io/arcsin1/pen…

MutationObserver是现代浏览器提供的Web API,用于检测DOM中的变化。使用此API,可以侦听新添加或删除的节点,属性更改或文本节点文本内容的更改。

优点:

  1. 可以知道dom渲染完耗时,来优化后面的dom节点增删改查
  2. 比事件委托监听,它会监听 DOM 可能发生的每个变化并且性能更优,因其会批量 DOM 变化之后才触发回调事件。(svg渲染可以参考)

缺点:

  1. 耗时任务,数据累积越多,后面等待时间和执行时间越久

Canvas篇(请参考代码数据量调式)

示例:codepen.io/arcsin1/pen…

Canvas比svg来说提供的功能更原始,适合像素处理,动态渲染和大数据量绘制 优点

  1. 绘制百万级别数据毫无压力(已有demo)
  2. 渲染效率比起svg更高
  3. 在渲染地图和数据场景复杂的时候效率很高
  4. 离屏Canvas
    • 在内存中进行并且离屏canvas的任何操作都不会导致页面变(重绘、重排)
    • 还可以减少冗余操作

web worker

我尝试了web worker和MutationObserver 一起实践 是可行的,优化会更好,当然你可以去试试

Web Worker的基本原理就是在当前javascript的主线程中,使用Worker类加载一个javascript文件来开辟一个新的线程,起到互不阻塞执行的效果。 优点

  1. 独立与主线程处理数据,利用web worker我们可以在前端执行一些复杂的大量运算而不会影响页面的展示。
  2. 可以多个worker处理不同的复杂数据然后给到主线程,而不影响主线程
  3. 其实web worker还有个优点: 就是会对数据结构化克隆(更深层次的克隆),这一块可以谷歌到专业文档

webGL

数据量极大的数据可视化场景,利用CPU,GPU和显卡极大提升渲染速度

结尾

也算是个人探索,当然你有更好的方式,可以提出来我们一起探究,谢谢