浅谈CSS重绘和回流(重排)—— 如何减少重绘和回流(重排)

浏览器的渲染过程

浅谈CSS重绘和回流(重排)—— 如何减少重绘和回流(重排)

  1. 解析HTML,构建DOM树

  2. 解析CSS,生成CSS规则树

  3. 合并DOM树和CSS规则,生成render树

  4. 布局render树(Layout/reflow),负责各元素尺寸、位置的计算

  5. 绘制render树(paint),绘制页面像素信息

  6. 浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上
    浅谈CSS重绘和回流(重排)—— 如何减少重绘和回流(重排)

基本概念

  • 重绘:当页面元素样式改变不影响元素在文档流中的位置时(如background-colorborder-colorvisibility),浏览器只会将新样式赋予元素并进行重新绘制操作。

  • 回流:当渲染树render tree中的一部分或全部因为元素的规模尺寸布局隐藏等改变时,浏览器重新渲染部分DOM或全部DOM的过程

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

什么时候会触发回流或重绘?

  • 添加或删除可见的DOM元素

  • 元素的位置发生变化

  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)

  • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。

  • 页面渲染初始化

  • 浏览器的窗口resize尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

  • 最复杂的一种:获取某些属性,引发回流

    (1) offset(Top/Left/Width/Height)
    (2) scroll(Top/Left/Width/Height)
    (3) cilent(Top/Left/Width/Height)
    (4) width,height
    (5) 调用了getComputedStyle()或者IE的currentStyle

如何减少重绘和回流(重排)

一、 CSS中避免回流、重绘

  1. 尽可能在DOM树的最末端改变class
  2. 避免设置多层内联样式
  3. 动画效果应用到position属性为absolute或fixed的元素上
  4. 避免使用table布局
  5. 使用css3硬件加速,可以让transform、opacity、filters等动画效果不会引起回流重绘

二、 JS操作避免回流、重绘

  1. 避免使用JS一个样式修改完接着改下一个样式,最好一次性更改CSS样式,或者将样式列表定义为class的名称
  2. 避免频繁操作DOM,使用文档片段创建一个子树,然后再拷贝到文档中
  3. 先隐藏元素,进行修改后再显示该元素,因为display:none上的DOM操作不会引发回流和重绘
  4. 避免循环读取offsetLeft等属性,在循环之前把它们存起来
  5. 对于复杂动画效果,使用绝对定位让其脱离文档流,否则会引起父元素及后续元素大量的回流

讲在后面