回流和重绘
- 回流(Reflow):
- 回流是指浏览器必须重新计算文档中元素的位置和几何结构的过程。当页面布局发生改变时,比如添加、删除、修改元素的尺寸、内容或样式,或者浏览器窗口大小发生变化时,就会触发回流。
- 回流是一种相对较为昂贵的操作,因为它涉及重新计算元素的几何属性,然后进行重新布局。因此,频繁地触发回流会导致页面性能下降。
- 重绘(Repaint):
- 重绘是指当元素的外观发生改变,但是并不影响其布局的情况下,浏览器需要更新元素的可视化呈现过程。比如修改元素的颜色、背景色、边框样式等。
- 重绘的开销相对较小,因为它只需要更新元素的可视化呈现,而不涉及重新计算布局。
何时发生回流
- 页面渲染初始化
- 调整浏览器窗口大小
- 内容改变——比如字体、文本改变或者用户在 input 框中输入文字
- 元素位置、尺寸改变——边距、填充、边框、宽度和高度,图片大小改变而引起的计算值宽度和高度
- 增加或者移除样式表
- 激活 CSS 伪类,比如 :hover (IE 中为兄弟结点伪类的激活)
- 操作 class 属性
- 添加或者删除可见的 DOM 元素
- 计算 offsetWidth 和 offsetHeight 属性
- 设置 style 属性的值
盒子模型相关属性会触发回流 | width/height/padding/margin/display/border-width/border |
---|---|
定位属性及浮动会触发回流 | top/bottom/left/right/position/float/clear |
改变节点内部文字结构也会触发回流 | text-align/overflow/font-weight/font-family/line-height/vertival-align/font-size |
修改时只触发重绘的属性 | color/border-style/border-radius/visibility/text-decoration/background 系列/outline/box-shadow |
避免回流
- 在 JavaScript 中尽量避免直接操作样式属性,而是使用 CSS 类来修改样式,并使用一次性修改多个样式属性的方式。
- 使用 CSS3 的硬件加速特性,如使用
transform
和opacity
进行动画效果,而不是改变元素的位置属性。 - 避免使用 table 布局
- 让要操作的元素进行”离线处理”,处理完后一起更新
- 使用 DocumentFragment 进行缓存操作,引发一次回流和重绘;
- 使用 display:none,先设置元素为 display:none;然后进行页面布局等操作;设置完成后将元素设置为 display:block;这样的话就只引发两次重绘和重排;
- 使用 cloneNode(true or false) 和 replaceChild 技术,引发一次回流和重绘;