前端性能优化-如何一次渲染10万条数据

1,349 阅读4分钟

1. 直接渲染

让我们看看有什么样的结果吧

效果展示

缺点 :

  • 这样会加载起来比较慢。
  • 页面渲染很久
  • 十万次的回流

2. requestAnimationFrame + fragment(时间分片)

requestAnimationFrame 是浏览器提供的一个用于优化动画性能的 API。它的作用是请求浏览器在下次重绘之前执行指定的回调函数,以保证动画的流畅性和性能。

在 Web 开发中,通常使用 JavaScript 来创建动画效果。过去常用的方法是使用 setIntervalsetTimeout 来反复执行更新动画状态的代码,但这些方法存在一些问题,比如:

  1. 时间不准确:setInterval 和 setTimeout 的时间间隔不一定准确,可能会导致动画卡顿或者过度绘制。
  2. 不受垂直同步信号控制:这些方法不能与浏览器的垂直同步信号(即垂直同步刷新率)同步,可能导致动画撕裂或不稳定。

requestAnimationFrame 的出现解决了这些问题。它的工作原理是,浏览器会在每次重绘(通常是每秒 60 次)之前调用注册的回调函数,以确保动画在适当的时机进行更新,同时与垂直同步信号保持同步,提高了动画的流畅性和性能。

使用 requestAnimationFrame 的基本流程如下:

  1. 定义一个更新动画状态的回调函数。
  2. 使用 requestAnimationFrame 注册这个回调函数,浏览器会在下次重绘之前调用它。
  3. 在回调函数中更新动画状态。
  4. 在回调函数中再次调用 requestAnimationFrame,以请求下一帧动画。

这样就能够实现一个基于 requestAnimationFrame 的流畅、高性能的动画效果。

fragment在 JavaScript 中,“fragment” 并没有一个特定的内置概念或者语言特性,但在某些情况下,“fragment” 可以指代一种虚拟的 DOM 元素容器或者文档片段。

文档片段(DocumentFragment) : 在原生 JavaScript 中,文档片段(DocumentFragment)是一种特殊的 DOM 节点,它可以作为一个轻量级的容器,用于临时存放 DOM 元素。文档片段本身不会直接插入到文档中,而是可以包含其他 DOM 元素,当文档片段插入到文档中时,它的子元素会被移动到目标位置,这样可以减少 DOM 操作的性能消耗。

效果展示

fragment是虚拟文档碎片,我们一次for循环产生 20 个li的过程中可以全部把真实dom挂载到fragment上,然后再把fragment挂载到真实dom上,这样原来需要回流十万次,现在只需要回流100000 / 20次,减少了回流的次数

3. 虚拟列表

效果展示

当用户滚动页面时,JavaScript 部分起到了关键作用:

  1. 生成数据:通过循环生成了包含 10 万条假数据的数组 data。这些数据将被用于填充列表中的条目。
  2. 渲染条目renderItems(startIndex, endIndex) 函数负责渲染列表中的条目。传入的参数是起始索引和结束索引,表示当前可见区域内的数据范围。该函数会创建 <div> 元素来表示每个条目,并将它们附加到容器中。
  3. 处理滚动事件handleScroll() 函数被绑定到容器的滚动事件上。每当用户滚动容器时,该函数被触发。它计算出当前滚动位置,根据滚动位置计算出可见的条目范围,并调用 renderItems() 函数重新渲染可见的条目。
  4. 初始化和滚动时的处理:在页面加载完成后,会首先调用 renderItems() 函数渲染首屏可见的条目。此后,当用户滚动容器时,会触发滚动事件,进而调用 handleScroll() 函数来动态更新可见的条目。

这样的实现方式带来了性能的提升,因为只有可见区域内的条目会被实际渲染到页面上,而不是一次性渲染整个数据集。这对于大型数据集来说尤为重要,因为它能够减少页面渲染的工作量,从而提高页面加载速度和用户体验。