回流 和 重绘

回流

就是页面布局发生变化。

重绘

就是节点需要更改外观而不会影响布局。

和 Event Loop 的关系

1. 回流 和 重绘 发生在 Event Loop 执行完微任务后,因为浏览器是 60Hz 的刷新率,每 16.6ms 才会更新一次。

2. 然后判断是否有 resize 或者 scroll 事件,有的话会去触发事件,所以 resize 和 scroll 事件也是至少 16ms 才会触发一次,并且自带节流功能

3. 更新css动画并触发对应事件

4. 判断是否触发了 media query

5. 判断是否有全屏操作事件

6. 执行 requestAnimationFrame 回调

7. 执行 IntersectionObserver 回调,该方法用于判断元素是否可见,可以用于懒加载上

8. 更新界面

9. 如果在一帧中有空闲时间,就会去执行 requestIdleCallback 回调。

IntersectionObserver

例如这样写,每次滚动到可以看到这个 img 元素时候,就会触发一次回调

let ob = new IntersectionObserver(e => {
    console.log(e)
})
ob.observe(document.querySelectorAll('img')[0])

observe 可以多次,回调的 e 是一个数组,根据 observe 的顺序返回对应的信息

RequestIdleCallback

例如这样写,调用 a() 后,浏览器会在空闲的时候 log 1

function a() {
    console.log(1)
    requestIdleCallback(a)
}

优化渲染速度

1. 用 transform 代替 top

2. 用 visibility: hidden 代替 display:none

3. 不要在循环里操作dom

4. 不要使用 table 布局, 可能很小的一个小改动会造成整个 table 的重新布局

5. JS动画实现的速度的选择,动画速度越快,回流次数越多,也可以选择使用 requestAnimationFrame

6. CSS 选择符从右往左匹配查找,避免节点层级过多

7. 将频繁重绘或者回流的节点设置为图层 ( will-change属性 和 video、iframe 标签)

如何判断渲染性能

查看 DOMContentLoaded 时间触发的时机。这个事件触发越早,说明渲染速度越快。

猜你喜欢

转载自www.cnblogs.com/amiezhang/p/11450822.html