重绘与重排 | 青训营

133 阅读2分钟

浏览器页面生成过程

  • HTML 被 HTML 解析器解析成 DOM 树、CSS 被 CSS 解析器解析成 CSSOM 树
  • 结合 DOM 树和 CSSOM 树,生成渲染树(Render Tree)
  • 生成布局(flow),浏览器在屏幕上“画”出渲染树中的所有节点,将布局绘制(paint)在屏幕上,显示出整个页面

页面渲染完成后,若JS操作了DOM节点,根据JS对DOM操作动作的大小,浏览器对页面进行重绘或是重排

重绘(repaint)

  • 屏幕的一部分要重绘。渲染树节点发生改变,但不影响该节点在页面当中的空间位置及大小。譬如某个div标签节点的背景颜色、字体颜色等等发生改变,但是该div标签节点的宽、高、内外边距并不发生变化,此时触发浏览器重绘(repaint)。
  • 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。

重排(reflow)

  • 也有称回流,当渲染树节点发生改变,影响了节点的几何属性(如宽、高、内边距、外边距、或是float、position、display:none;等等),导致节点位置发生变化,此时触发浏览器重排(reflow),需要重新生成渲染树。

    • 譬如JS为某个p标签节点添加新的样式:"display:none;"。导致该p标签被隐藏起来,该p标签之后的所有节点位置都会发生改变。此时浏览器需要重新生成渲染树,重新布局,即重排(reflow)。

重排何时发生

当页面布局和几何属性改变时就需要重排。下述情况会发生浏览器重排:

  • 添加或者删除可见的DOM元素
  • 元素位置改变——display、float、position、overflow等等
  • 元素尺寸改变——边距、填充、边框、宽度和高度
  • 内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变
  • 页面渲染初始化(无法避免)
  • 浏览器窗口尺寸改变——resize事件发生时

重排影响的范围:

由于浏览器渲染界面是基于流式布局模型的,所以触发重排时会对周围DOM重新排列,影响的范围有两种:

  • 全局范围:从根节点html开始对整个渲染树进行重新布局。
  • 局部范围:对渲染树的某部分或某一个渲染对象进行重新布局

重排优化建议

1. 减少重排范围

尽量以局部布局的形式组织html结构,尽可能小的影响重排的范围。

2. 减少重排次数

  • 样式集中改变
  • 分离读写操作
  • 将 DOM 离线
  • 使用 absolute 或 fixed 脱离文档流
  • 优化动画