浏览器的重绘与重排
- DOM 树:解析 HTML 构建 DOM(DOM 树)
- CSS 树:解析 CSS 构建 CSSOM(CSS 树)
- 渲染树:CSSOM 和 DOM 一起生成 Render Tree(渲染树)
- 布局(layout):根据Render Tree浏览器就知道网页中有哪些节点,以及各个节点与 CSS 的关系,从而知道每个节点的位置和几何属性
(重排)
- 绘制(Paint):根据计算好的信息绘制整个页面
(重绘)
重排(回流)
浏览器渲染过程中的步骤4(几何属性发生变化)
当 DOM 的变化影响了元素的几何属性(宽和高), 比如改变边框宽度或给段落增加文字,导致行数增加 ,浏览器需要重新计算元素的几何属性
,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构建渲染树。这个过程称为 “重排”。
触发重排的情况
- 添加或删除可见的 DOM 元素
- 元素位置改变
- 元素尺寸改变(包括:外边距、内边距、边框厚度、宽度、高度等属性改变)
- 元素改变
font-size
和font-family
- 内容改变。例如:文本改变或图片被另一个不同尺寸的图片代替
页面渲染器初始化
浏览器窗口尺寸改变
- 当
滚动条出现
时,会触发整个页面的重排 JS 获取 Layout 属性值
(如:offsetLeft、scrollTop、getComputedStyle 等)也会引起重排。因为浏览器需要通过回流计算最新值。
Layout 属性值(强制刷新队列)
- offsetTop , offsetLeft , offsetWidth , offsetHeight
- scrollTop , scrollLeft , scrollWidth , scrollHeight
- clientTop , clientLeft , clientWidth , clientHeight
- getComputedStyle() ( currentStyle in IE )
重绘
浏览器渲染过程中的步骤5(几何属性无变化)
当渲染树中的元素外观(如:颜色)发生改变,不影响布局时,不影响元素的几何属性
,这个过程称为 “重绘”。
重排一定会引起重绘,而重绘则不一定会引起重排
display: none
会导致重排和重绘
visibility: hidden
只会导致重绘
优化
重绘和重排操作都是代价昂贵的操作,它会导致 WEB 应用程序的 UI 反应迟钝。所以,应当尽可能减少这类过程的发生。
为了减少重绘重排带来的性能消耗,可以通过以下几点改善 web 应用:
1. 批量修改 DOM 和样式
var el = document.getElementById('mydiv');
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';
以上代码会导致三次重排,改为:
var el = document.getElementById('mydiv');
el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';
.
2. 脱离文档流
将需要多次重排的元素,position 属性设置为 absolute 或 fixed,这样元素就脱离了文档流,它的变化不会影响到其他元素。例如有动画效果的元素就最好设置为绝对定位。
.
3. 缓存到局部变量,减少页面布局信息的访问次数
缓存 Layout 属性值,如:var left = elem.offsetLeft;
这样,多次使用 left 只产生一次回流