css优化之重排与重绘

浏览器的渲染机制

主要分为以下几个步骤:

  • 解析HTML(HTML Parser)
  • 构建DOM树(DOM Tree)
  • 渲染树构建(Render Tree)
  • 绘制渲染树(Painting)

浏览器取回代码后,首先会构造DOM树,根据HTML标签,构造DOM树。

之后会解析CSS样式,解析的顺序是浏览器的样式 -> 用户自定义的样式 -> 页面的link标签等引进来的样式 -> 写在style标签里面的内联样式

 

 

 

 

 

 

 

 

 

 

 

 

网页生成的时候,至少会渲染一次。用户访问的过程中,还会不断重新渲染。

重新渲染,就需要重新生成布局和重新绘制。前者叫做重排(reflow),后者叫做重绘(repaint)。

需要注意的是,重绘不一定需要重排,重排必然导致重绘。

为了提高网页性能,就要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。

 

慎重选择高消耗的样式

什么 CSS 属性是高消耗的?就是那些绘制前需要浏览器进行大量计算的属性。

  • box-shadows

  • border-radius

  • transparency

  • transforms

  • CSS filters(性能杀手)

 

什么是reflow

浏览器为了重新渲染部分或整个页面,重新计算页面元素位置和几何结构的进程叫做reflow.

通俗点说就是当开发人员定义好了样式后(也包括浏览器的默认样式),浏览器根据这些来计算并根据结果将元素放到它应该出现的位置上,这个过程叫做reflow.

由于reflow是一种浏览器中的用户拦截操作,所以我们了解如何减少reflow次数,及DOM的层级,css效率对refolw次数的影响是十分有必要的。

reflow(回流)是导致DOM脚本执行效率低的关键因素之一,页面上任何一个节点触发了reflow,会导致它的子节点及祖先节点重新渲染。

<body>
  <div class="hello">
    <h4>hello</h4>
    <p><strong>Name:</strong>BDing</p>
    <h5>male</h5>
    <ol>
      <li>coding</li>
      <li>loving</li>
    </ol>
  </div>
</body>

当p节点上发生reflow时,hello和body也会重新渲染,甚至h5和ol都会收到影响。

 

什么时候会导致reflow发生呢?

  • 改变窗口大小
  • 改变文字大小
  • 添加/删除样式表
  • 内容的改变,(用户在输入框中写入内容也会)
  • 激活伪类,如:hover
  • 操作class属性
  • 脚本操作DOM
  • 计算offsetWidth和offsetHeight
  • 设置style属性
常见的重排元素   
width height padding margin
display border-width border top
position font-size float text-align
overflow-y font-weight overflow left
font-family line-height vertical-align right
clear white-space bottom min-height

 

 

 

 

 

 

 

怎么减少 Reflow

  1. 不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM 的 className

  2. 把 DOM 离线后修改,比如:先把 DOM 给 display:none (有一次 Reflow),然后你修改100次,然后再把它显示出来

  3. 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量

  4. 尽可能不要修改影响范围比较大的 DOM

  5. 为动画的元素使用绝对定位 absolute / fixed

  6. 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局

 

什么是repaint

repaint是在一个元素的外观被改变,但没有改变布局的情况下发生的,如改变了visibility、outline、background等。当repaint发生时,浏览器会验证DOM树上所有其他节点的visibility属性。·

通俗来说,就是当各种盒子的位置、大小以及其他属性,例如颜色、字体都确定下来后,浏览器便把这些元素都按照各自的特性绘制一遍,于是页面的内容出现了,这个过程叫做repaint

 

避免过分重绘(Repaints)

当元素改变的时候,将不会影响元素在页面当中的位置(比如 background-color, border-color, visibility),浏览器仅仅会应用新的样式重绘此元素,此过程称为 Repaint

 

常见的重绘元素   
color border-style visibility background
text-decoration background-image background-position background-repeat
outline-color outline outline-style border-radius
outline-width box-shadow background-size

 

 

 

 

 

 

优化动画

css3 动画是优化的重中之重。除了做到上面两点,减少 Reflow 和 Repaints 之外,还需要注意以下方面。

启用 GPU 硬件加速

GPU(Graphics Processing Unit) 是图像处理器GPU 硬件加速是指应用 GPU 的图形性能对浏览器中的一些图形操作交给 GPU 来完成,因为 GPU专门为处理图形而设计,所以它在速度和能耗上更有效率。
GPU 加速可以不仅应用于3D,而且也可以应用于2D。这里, GPU 加速通常包括以下几个部分:Canvas2D布局合成(Layout Compositing), CSS3转换(transitions)CSS3 3D变换(transforms)WebGL视频(video)

/*
 * 根据上面的结论
 * 将 2d transform 换成 3d
 * 就可以强制开启 GPU 加速
 * 提高动画性能
 */
div {
  transform: translate(10px, 10px);
}
div {
  transform: translate3d(10px, 10px, 0);
}

 

需要注意的是,开启硬件加速相应的也会有额外的开销,参见这篇文章 CSS 硬件加速的好与坏·

参考以下文章:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章