跳到主要内容

回流和重绘

  1. 回流(Reflow):
    • 回流是指浏览器必须重新计算文档中元素的位置和几何结构的过程。当页面布局发生改变时,比如添加、删除、修改元素的尺寸、内容或样式,或者浏览器窗口大小发生变化时,就会触发回流。
    • 回流是一种相对较为昂贵的操作,因为它涉及重新计算元素的几何属性,然后进行重新布局。因此,频繁地触发回流会导致页面性能下降。
  2. 重绘(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 的硬件加速特性,如使用 transformopacity 进行动画效果,而不是改变元素的位置属性。
  • 避免使用 table 布局
  • 让要操作的元素进行”离线处理”,处理完后一起更新
    • 使用 DocumentFragment 进行缓存操作,引发一次回流和重绘;
    • 使用 display:none,先设置元素为 display:none;然后进行页面布局等操作;设置完成后将元素设置为 display:block;这样的话就只引发两次重绘和重排;
    • 使用 cloneNode(true or false) 和 replaceChild 技术,引发一次回流和重绘;