跳到主要内容

什么是重绘和回流?

对于 dom 上的性能优化追根揭底是对重绘和节流的把控。

重绘: DOM 节点元素没有删除,增加,移动,尺寸改变的情况,元素只有样式上的改变。浏览器针对这个样式改变对视图进行一个重新绘制。这个过程,叫做重绘。比如 color,background 的改变。就是典型的重绘。

回流:回流也叫做重排,指 DOM 节点元素出现删除,增加,移动,尺寸改变的情况。浏览器需要针对元素进行重新构建和渲染。这个过程被称为回流。

浏览器在接收到一个 html 文档的时候会做些什么?↓

浏览器在接收到一个 html 文档的时候,会同时构建 DOM 节点树和 CSS 渲染树。注意,出于对浏览器性能上的考虑,浏览器并不会等待 DOM 节点树构建完毕后再去构建 CSS 渲染树,所以 DOM 节点树的构建和 CSS 渲染树的构建是同步的。

浏览器绘制流程如下 👇

20230301151255

在这个过程中,如果在 DOM 节点树中扫描到 JS 代码,DOM 节点树和 CSS 渲染树会停止构建,浏览器把控制权交给 javascript 的引擎。并且等待这一段 JS 代码运行完毕后再继续构建(因为浏览器不知道 js 代码是否会对后续的节点进行操作,万一那段 JS 代码是把 dom 即将构建的节点删掉咋办,那就白建了。所以需要等待混在 dom 中的 js 代码执行完毕之后再进行构建)。

重绘不一定会导致回流。但是回流一定需要重绘。而且,回流的性能消耗远大于重绘。

为了让重绘和回流的影响对我们的产品影响降低到最小,vue,react,angular 等框架都使用了虚拟 dom 技术,就是避免浏览器进行不必要的重绘和回流。

重绘和回流的触发场景

重绘的触发场景 ↓

  • 颜色的修改(color,background-color)
  • 阴影的修改
  • visibility:hidden
  • css3 的 translate
  • ...

回流的触发场景 ↓

  • 删除或者新增一个节点元素
  • 元素位置的改变,比如 float,position,overflow,display 等等
  • 元素尺寸的改变,比如 margin,padding,height,width 等等
  • 初始化构建 DOM 树的时候
  • 窗口尺寸的变化 也就是 resize 事件发生的时候
  • 填充内容的改变(内容撑大了某一个节点,内容改变,包含它的节点大小自然跟随调整。)
  • 读取某一个元素的时候,比如 offsetLeft,offsetTop,offsetHeight,offsetWidth,  clientTop,clientLeft,clientWidth,clientHeight,  scrollTop,scrollLeft,scrollWidth,scrollHeight,  width,height 等等
  • ...

减少重绘和回流

  • 当我们需要动态改变某一个元素的位置的时候,不要使用 position,使用 translate,两种功能都可以实现元素的位移,但是 position 会触发回流,但是 translate 只会触发重绘。
  • 尽量不要使用 table 布局,因为 table 中某一个小小的改动就会导致整个 table 进行重新布局。而且 table 的重新构建往往是其他元素的几倍。
  • 避免频繁获取节点或者某一个会导致回流的元素。(例如 element.offsetLeft,document.getElementById)仅仅是读取这个元素就会导致回流,所以,条件允许的话,读取一次就缓存起来。避免多次读取。
  • 可以使用 css 预先构建好的样式不要使用 js 去动态添加。
  • 再 translate 无法满足元素移动需求的情况下,让元的 position 变成 absolute 或者 fixed 也就是脱离文档流之后再去移动,否则像 relative 此类状态去移动的话会导致后续全部元素陷入高频的回流状态。
  • 需要隐藏元素的时候使用 visibility:hidden 而非 display:none.display:none 会导致回流但是 visibility:hidden 不会
  • 离线操作:对 dom 进行操作的时候,可以先使用 diaply:none 将元素离线,操作完成以后再 display:block 显示。
  • ....

总结

  • 重绘:尺寸没变,大小没变,也没有突然出现,改变的仅仅是颜色,轮廓等。
  • 回流: 尺寸变了,大小变了,或者突然新增了一个节点。
  • 重绘不一定会引发回流,但是回流一定会引发重绘。
  • 开发中需要尽量避免重绘和回流。
信息

作者:工边页字 链接:https://juejin.cn/post/7106040916862828557 来源:稀土掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。