文章目录
  1. 1. 全量计算的性能瓶颈
  2. 2. 基于可视范围的预热计算
  3. 3. 结合 50ms 计算任务拆分
  4. 4. 新的数据变更计算
  5. 5. 结束语

前面我们在《复杂渲染引擎架构与设计–5.分片计算》一文中介绍了分片计算,即将需要计算的内容进行拆分,拆分成约每 50 ms 一个的任务。

在这个方案中,我们维护了一个待计算区域,将页面中所有未完成的计算任务放在里面,等待异步每个计算任务进行计算。

全量计算的性能瓶颈

《复杂渲染引擎架构与设计–5.分片计算》中的方案,已经基本解决大多数场景下的性能问题。但面对超大页面的渲染计算来说,可能依然存在以下瓶颈:

  • 区域合并和碰撞检测,在待计算任务过多时容易产生性能问题。尤其在列数多的场景下,按行计算的每次任务计算范围都十分仅限
  • 计算任务过多,当一个页面中的内容十分多的时候(比如一万多列、几十万行的表格),我们还需要考虑是否所有内容都需要异步计算完毕,是否存在资源的浪费

因此,我们可以考虑更合适的异步方案,该方案需要考虑:

  1. 尽量减少计算内容范围,减少资源浪费。
  2. 尽量提前计算好可能需要的资源,减少用户等待时间。

这两点要求,看起来有点相互矛盾,毕竟一个要减少计算,一个却要增加计算。但实际上从用户的角度出发,我们的确可以做的更好。

基于可视范围的预热计算

我们可以这样调整渲染引擎的计算设计:

  1. 不再计算整个页面所有的数据,而是基于当前停留的界面可视范围来进行计算。
  • 优先计算当前可视范围的渲染数据
  • 以可视范围为基础倍数,异步计算横向 3 倍、纵向 15 倍的渲染层数据,放置到异步计算
  1. 每个倍数范围的计算,作为单独的一个计算任务,一个计算任务计算后,会通过任务调度进行下一个。任务优先顺序为:当前视图范围 -> 视图范围下方 -> 视图范围上方 -> 视图范围右侧 -> 视图范围左侧。
  2. 用户进行滚动操作时,会在滚动停止后,再基于停止后的界面,重复 1 步骤,已计算完成的数据会进行缓存,跳过已计算的内容不重复计算。

举个例子,当界面停留不滚动时,当前可视范围有 10 列 50 行,则会计算 10 _ 3 = 30 列、 50 _ 15 = 750 行的数据。

当然,横向 3 倍、纵向 15 倍这个数字也是可以进行调整的,可以埋点记录用户行为,然后观察用户习惯后进行调整。

该方案的优点在于:

  • 每个计算任务单元格数量不会十分大,可有效避免按行计算在极端条件下可能计算量很大的场景
  • 不需要计算整表完整的数据,可有效减少计算量
  • 可提前预热可视区域附近的区域(横向 3 倍,纵向 15 倍),在用户滚动时可快速渲染
  • 无需维护待计算区域任务,无需进行碰撞检测和区域合并,简化了计算性能

至于为什么任务优先顺序会是:下、上、右、左,可参考另外一篇文章《前端性能优化–预加载顺序设计》

结合 50ms 计算任务拆分

基于可视区域的计算方案,在大多数场景下都不会有性能问题,但还有一种场景:单个可视区域的计算量十分大,比如用户缩放到 10% 的时候,可能单个计算任务就会存在卡顿。

因此,我们可以结合之前提到的 50ms 任务拆分(参考《让你的长任务在 50 毫秒内结束》一文),在异步计算的时候,当当前任务计算已超出 50ms 范围,则结束任务,释放出主线程给用户交互。

为此,我们可能需要:

  • 支持脏区标记,标记哪些已计算的数据不再为最新
  • 支持是否计算完成标记,供异步任务计算时判断是否跳过

基于此方案,我们需要调整异步任务管理:

  1. 使用新的异步任务(滚动停止时,构建当前可视区域的横向 3 倍、纵向 15 倍异步任务)。
  2. 同步计算可视范围内数据,异步计算可视范围附近区域(考虑使用 requestAnimationFrame 的方式进行异步)。
  3. 当可视范围内单元格数量很多时(缩放倍率较小场景下),按照 50ms 进行二次拆分计算。

新的数据变更计算

除了加载现有的数据,当后续数据发生变更的时候,还需要将一些已经计算完毕的数据进行重算,在这样的情况下,我们还需要将一些已经完成计算的数据进行标记,并进行重算。

在脏区标记完后,我们依然进行可视区域的预热计算,建立可视区域外的各个计算区域任务。当任务执行时,发现区域内存在脏数据,则将这些数据进行重算。计算完成后,则更新数据缓存,并重置脏数据标记位。

结束语

当我们在使用各种技术方案尝试优化的时候,不妨也从用户的角度考虑下,用户最可能的行为是怎样的。大多数用户并不需要完整的网页内容,他们很多时候只会翻阅自己关心的内容,看完之后便会关掉。

我们还可以通过埋点去分析用户行为,通过确切的数据去调整我们的具体优化方案。

码生艰难,写文不易,给我家猪囤点猫粮了喵~

B站: 被删

查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢

如果你想要关注日常生活中的我,欢迎关注“牧羊的猪”公众号噢

作者:被删

出处:https://godbasin.github.io

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

文章目录
  1. 1. 全量计算的性能瓶颈
  2. 2. 基于可视范围的预热计算
  3. 3. 结合 50ms 计算任务拆分
  4. 4. 新的数据变更计算
  5. 5. 结束语