文章目录
  1. 1. 页面内的元素优先级划分
  2. 2. 降级渲染
    1. 2.1. 页面帧率
    2. 2.2. 滚动距离
    3. 2.3. 渲染插件的降级
  3. 3. 降级渲染的启动和停止
  4. 4. 结束语

前面我们在《复杂渲染引擎架构与设计–6.增量计算》一文中介绍了滚动过程中的增量渲染方案,通过减少渲染计算量或绘制量的方式,来提升页面滚动的流畅度。

除此之外,当滚动距离较远时,增量渲染并不能达到预期的优化效果,此时我看还需要考虑降级渲染。

页面内的元素优先级划分

当用户打开一个大的页面时,除了使用搜索获取关键信息,还可能会快速滚动来翻阅整体内容,然后找到关注的信息进行详细查阅。增量渲染的方案,核心是将上一帧的内容尽可能复用到下一帧里,因此在快速滚动的场景下(比如拖动滚动条滚动),页面中可能并没有多少可复用的内容。

在这样的场景下,如果需要渲染的内容实在很多,我们可以对页面内容进行优先级划分。

该如何进行优先级划分呢?这个可能需要结合业务的具体情况进行分析,比如:

  • 分段分组的内容:标题、副标题等
  • 方便用户定位位置的内容:文本框、图片、背景色等

像图片这种渲染可能会比较耗时,那么可以用占位符等方式来进行骨架渲染,让用户能快速定位到对应位置之后,再进行详细内容的渲染。

具体到在线表格的场景下,首先行列位置十分重要,同时方便用户定位位置的还有单元格背景色、边框线、图片等等内容。我们可以这样拆分优先级:

  • 行列头、行列序号、选区
  • 单元格背景色、边框线
  • 图片(占位符)
  • 文本内容
  • 其他格式内容/图标(格式错误角标、下拉按钮、icon 内容等)
  • 真实图片信息
  • 其他

拆分出优先级后,我们可以进行降级的渲染,在流畅度不高的情况下,优先渲染高优先级的内容,保证用户的滚动流畅体验。

降级渲染

通过优先级的划分,我们可以在渲染过程中,保证滚动操作的流畅度。具体方式为:根据页面帧率和用户滚动的距离,来进行降级的渲染。

页面帧率

理想情况下,检测到页面帧率开始下降的情况下,则考虑进入降级渲染的场景。

页面帧率可以使用requestAnimationFrame来进行计算,当然前提还需要是页面进行了滚动操作,否则的话只是单纯当前页面绘制慢则进行降级,用户会感觉页面内容突然减少,体验较差。

我们可以在页面开始滚动时,监听 rAF 变化来计算 FPS,当 FPS 明显下降到不流畅的时候,则进入降级渲染,并根据帧率来调整降级渲染的级数。比如(简单举例):

  • 0 < FPS < 10: 最高级别的降级渲染,只渲染边框线和单元格背景色
  • 10 < FPS < 20: 中级别的降级渲染,除了边框线和单元格背景色以外,还渲染单元格富文本内容
  • 20 < FPS < 30: 低级别的降级渲染,除了边框线和单元格背景色、单元格以外,还渲染图片
  • 30 < FPS < 40: 最低级别的降级渲染,渲染仅附加内容(如角标、协作者光标、icon 等)以外的内容

滚动距离

在很多情况下,其实我们并不能很好地使用requestAnimationFrame来计算 FPS 帧率,因为 FPS 的计算需要一个累计过程,才能得到平均 1s 内的平均 FPS,同时频繁使用 rAF 本身也可能会影响到页面渲染性能。

所以,我们可以从别的角度来控制降级渲染的情况,比如使用用户页面滚动的快慢来控制优先级。

我们依然可以使用渲染本身,在两次渲染之间获取用户的滚动距离,根据滚动距离判断滚动速度,并以此来调整降级渲染的策略。比如,当页面进入滚动状态后,两次绘制之间的滚动距离:

  • 超过 20 屏内容:最高级别的降级渲染
  • 10 屏 < 滚动距离 < 20 屏:中级别的降级渲染
  • 5 屏 < 滚动距离 < 10 屏:低级别的降级渲染
  • 2 屏 < 滚动距离 < 5 屏:最低级别的降级渲染

当然,这里的渲染,除了 rAF 本身之外,还可以是 API 的调用如渲染层的 render 接口,或者是 canvas 的绘制。

渲染插件的降级

前面在《复杂渲染引擎架构与设计–2.插件的实现》一文中,我们介绍了除核心渲染内容以外,其他附加格式内容的渲染方式:使用渲染插件。

由于插件设计的存在,我们通过很简单的方式,就能实现降级渲染的能力。因为一些附加格式的渲染,都是使用渲染插件实现的,比如 icon 绘制、下拉菜单、角标、图片等等,我们可以十分轻易地将渲染插件进行降级优先级的归档。

当我们判断需要进行降级渲染时,可以直接通过优先级策略,来控制是否跳过某些插件的收集过程,便可以直接达到降级渲染的效果。

降级渲染的启动和停止

前面提到,进入降级渲染的前提条件是用户进行滚动,在滚动过程中通过不同的方式判断用户滚动“是否流畅”,如果检测到滚动不流畅的话,则根据卡顿程度进入到不同级别的降级渲染。

降级渲染,说白了就是减少页面渲染的内容,从而减轻每次渲染的耗时,提升用户的使用流畅度。

但当用户停止滚动、或是滚动较慢时,这时候可以认为用户需要聚焦阅读页面中的信息,因此这种时候我们还需要退出降级渲染模式,将页面内容进行完整渲染。

通过这样的方式,我们保证了用户滚动流畅度的同时,还确保了页面内容不会丢失。

结束语

本文介绍了当页面内容过多,用户在滚动时因为绘制较慢导致不流畅时,使用降级渲染的方式来保证用户的流畅度。

当然,其实说到底这个策略也会损耗了一些用户体验,但如果有更好的优化方式,我们也不需要使用到降级策略。很多时候,技术的决策便是在各种不同优劣的技术方案中,选出一种性价比更好、投入产出比更好的方案而已。

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

B站: 被删

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

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

作者:被删

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

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

文章目录
  1. 1. 页面内的元素优先级划分
  2. 2. 降级渲染
    1. 2.1. 页面帧率
    2. 2.2. 滚动距离
    3. 2.3. 渲染插件的降级
  3. 3. 降级渲染的启动和停止
  4. 4. 结束语