本文章内容来此 winter 老师的视频讲解 鉴定一下网络热门面试题:什么是回流和重绘?

回流(重排)

重排顾名思义,当某个元素的变化导致其他元素的布局(大小),这个时候就会触发 回流(重绘)

常见触发回流(重排的属性)

  • 盒模型

    • width, height、margin、padding、border、box-sizing等
  • 文字相关

    • font、word-space、letter-space、whitespace、text-align、vertical-align 等
  • 排版相关

    • position、float、display 等
  • HTML标签

    • image 等,行内可替换元素。

实用:动画能用 transform 就用,不会触发 relayout。

在js代码中触发 relayout

  • 如果我们在同步的一段js代码中修改多个会触发relayout的属性,这种情况下浏览器会把relayout 触发放到这段代码执行完成,在进行。

  • 如果我们将属修改和元素位置信息获取混合实用,那么会强制触发一次 relayout, 如果将下面两个操作放到循环里交替进行,在非动画场景下也会导致卡顿的(避免交替进行)。

    •   el.style.hegiht = "100px";
        let c = el.offsetHeight, b = el.getBoundingClientRect();
      

重绘(repaint)

这个操作我们无法避免,比如说鼠标滑过网页的时,会触发重绘去修复鼠标滑过路径盖住的部分。
无法避免也并不是说我们可以完全不管,现代网页中有一个 composition(组合) 的概念。

composition 出现的前提:现代网页中的元素是非常多的,如果把渲染树种的box逐个生成它的像素的位图,然后每次repaint 都把这些图重新画一遍,那么是非常耗时的。

compostion: 浏览器会把它觉得这辈子不会发生相对位置变化的元素 合成到一个 位图中,而合成的产物叫做 composition layer.

浏览器可能会猜错,比如我们有父子 两个div,浏览器猜测它们会发生相对变化,但是它不会发生相对变化,那么此时就会多生成一个位图。

所以我们能做的就是让浏览器尽量去猜对

  • 如果一个元素上有动画,那么给它加上 transform 属性,哪怕它一开始是默认值。
  • 尽量实用css动画
  • 用 will-change 提示浏览器(哪些会修改哪些不会修改),它不会有任何副作用。
  • 利用硬件加速,使用 transfrom 3d 相关的。利用 GPU 加速。

总结

回流(重排) 当元素改变某个属性时,导致其他元素的位置信息发生变化或大小发生变化时会触发重排,行内可替换元素的HTML标签加载也会触发重排。
重绘 当元素的样式信息等改变会触发重绘,重绘是不能够避免的。不过我们可以尽量减少重绘,和利用composition 提示,还有硬件加速等。

重排会伴随重绘,重绘不一定会重排。