前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Thinking--FastDom消除浏览器布局抖动

Thinking--FastDom消除浏览器布局抖动

作者头像
奋飛
发布2023-03-06 15:57:36
4950
发布2023-03-06 15:57:36
举报
文章被收录于专栏:Super 前端Super 前端

Thinking系列,旨在利用10分钟的时间传达一种可落地的编程思想。

对于大量操作 DOM 的场景,页面时常会出现卡顿现象,导致用户体验不佳。卡顿的原因是由于掉帧导致!!

掉帧

现在屏幕大部分的固定刷新频率为60Hz,浏览器会在这个间隔 16ms(

1000/60

)进行绘制操作,以确保流畅性。

显然,16ms 渲染一次是确保浏览器不卡顿的重点。如果没在 16ms 内进行一次渲染,则意味着该帧丢失了(掉帧)。

浏览器完成一次渲染,需要完成如下步骤:

  1. 处理 HTML 标记并构建 DOM 树。
  2. 处理 CSS 标记并构建 CSSOM 树。
  3. 将 DOM 与 CSSOM 合并成一个渲染树。
  4. 根据渲染树来布局,以计算每个节点的几何信息。
  5. 将各个节点绘制到屏幕上。

详细了解该部分,可查看 前端优化–关键渲染路径

为什么会丢帧?

javascript 为单线程,如果存在大量的 js 计算,会导致阻塞,绘制时间被延后,出现丢帧。

如何引起重绘?

代码语言:javascript
复制
// Suboptimal, causes layout twice.
var newWidth = aDiv.offsetWidth + 10; // Read
aDiv.style.width = newWidth + 'px'; // Write
var newHeight = aDiv.offsetHeight + 10; // Read
aDiv.style.height = newHeight + 'px'; // Write

// Better, only one layout.
var newWidth = aDiv.offsetWidth + 10; // Read
var newHeight = aDiv.offsetHeight + 10; // Read
aDiv.style.width = newWidth + 'px'; // Write
aDiv.style.height = newHeight + 'px'; // Write

http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html

requestAnimationFrame

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。

代码语言:javascript
复制
window.requestAnimationFrame(callback);

FastDom

fastdom 通过批处理 DOM 读/写操作 消除布局抖动。官方提供的两个示例:

关于动画:http://wilsonpage.github.io/fastdom/examples/animation.html

关于改变DOM宽高:http://wilsonpage.github.io/fastdom/examples/aspect-ratio.html

通过数据发现:FastDom > requestAnimationFrame > 原生(不借助任何函数)

剖析

代码语言:javascript
复制
fastdom.measure(() => { console.log('读DOM') })
fastdom.mutate(() => { console.log('写DOM') })
fastdom.measure(() => { console.log('读DOM') })
fastdom.mutate(() => { console.log('写DOM') })

// 读DOM 读DOM 写DOM 写DOM

其核心是通过批处理,将对 DOM 的读写操作进行分类管理,并一次性处理。

每一个 measure(读)/mutate(写) 操作任务都会被添加到对应的队列中。队列在下一帧使用 window.requestAnimationFrame() 执行。

FastDom 的目标是在应用程序的所有模块中像一个单例,返回相同实例,统一对 DOM 进行 读/写 操作。

源码地址:https://github.com/wilsonpage/fastdom/blob/HEAD/fastdom.js#L71-L72

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 掉帧
  • 如何引起重绘?
  • requestAnimationFrame
    • FastDom
      • 剖析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档