一分钟了解浏览器的回流与重绘【Reflows & Repaints】

52 阅读2分钟

一、是什么?

重绘:当某个元素的字体颜色等不影响布局的属性变化时,不需要重新构建渲染树,只需直接重新绘制页面即可;

回流:当某个元素的大小、位置发生了变化时,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树;

回流必将引起重绘,重绘不一定会引起回流

tips:当浏览器第一次加载资源时,确定节点的大小和位置称为布局。 浏览器在加载了一部分资源时,进行了渲染,当继续加载资源时,可能会对前面加载过的资源进行了修改,这可能就会发生回流和重绘。

二、什么导致?

很多种用户操作都可触发重排。例如:调整浏览器窗口的大小、使用涉及计算出的样式的 JavaScript 方法、在 DOM 中添加或移除元素,以及更改某个元素的类,等等。

  • 调整窗口大小
  • 更改字体
  • 添加或删除样式表
  • 内容更改,例如用户键入文本
  • 输入框
  • 激活CSS伪类,例如:hover(在IE中激活同级的伪类)
  • 操作类属性
  • 操纵DOM的脚本
  • 计算offsetWidth和offsetHeight
  • 设置style属性的属性

以上这些操作都会触发页面的回流或重绘。

三、如何减少?

图片.png

从上面的表格中可以清楚地看到,并非对 JavaScript 样式做出的所有更改都会导致在所有浏览器中进行重排,而且执行重排所需的时间也不尽相同。此外,新型浏览器在重排用时方面表现得更出色,这也是比较显而易见的。

下面是一些简单的准则,可帮助您尽可能缩短在网页中进行重排的用时:

  1. 非必要,避免使用表格进行布局。
  2. 尽可能减少 CSS 规则的数量,并移除未使用的 CSS 规则。
  3. 使用 style.cssText="xxx" 代替 style.width="xxx",或添加class一次性更改。
  4. 如果您想进行复杂的渲染更改(例如动画),使用 position-absolute 或 position-fixed 来实现。
  5. 避免频繁读取计算属性offsetWidthoffsetHeight等,如果确实需要多次使用,就用一个变量缓存起来
  6. 避免使用不必要且复杂的 CSS 选择器(尤其是后代选择器 h1 em {color:red;}),因为此类选择器需要耗用更多的 CPU 处理能力来执行选择器匹配。
  7. 减少不必要的 DOM 深度。在 DOM 树中的一个级别进行更改可能会致使该树的所有级别(上至根节点,下至所修改节点的子级)都随之变化。这会导致花费更多的时间来执行重排。

四、回流可视化

5月24日 (2) 00_00_00-00_00_30.gif

五、参考文章

# 尽可能减少浏览器重排

# Reflows & Repaints: CSS Performance making your JavaScript slow?