CSS的书写顺序对性能的影响你知道么?

时间:2020-10-24 作者:admin

先来看一段代码

width: 150px;
height: 150px;
font-size: 24px;
position: absolute;

当浏览器解析到position的时候,发现钙元素是绝对定位,需要脱离文档流,但是之前的属性都是按照常规解析的,所以不得不重新渲染,这时渲染引擎就系要接触该元素再文档中的占位,这样就有可能导致其他元素受到他的回流影响进而发生重排。

调整后代码

position: absolute;
width: 150px;
height: 150px;
font-size: 24px;

根本原因: reflow(回流)

其实是该元素回流导致,减少浏览器reflow(回流),就可以提升浏览器渲染dom的性能

那么问题来了?到底怎样才可以减少reflow(回流)呢?

要尽量避免,那就需要知道浏览器的渲染过程!

  1. 解析html构建dom树,解析css构建css树:将html解析成树形的数据结构,将css解析成树形的数据结构
  2. 构建生成render树:DOM树和CSS树合并之后形成的render树。
  3. 排版布局render树:有了render树,浏览器已经知道那些网页中有哪些节点,各个节点的css定义和以及它们的从属关系,从而计算出每个节点在屏幕中的位置。
  4. 绘制渲染render树:按照计算出来的规则,通过显卡把内容画在屏幕上。

*css代码从解析到显示到浏览器屏幕上,其实就是上面的2->3->4的过程。*

  • 浏览器并不是一获取到css样式就立即解析,而是根据css样式的书写顺序,将其对应dom树的结构而分布render样式,与DOM树合并完成并生成render树,也就是上面的第2步。
  • 然后遍历render树每个结点的css样式进行解析,此时的css样式的遍历顺序完全是按照之前的书写顺序。在解析过程中,一旦浏览器发现某个元素的定位变化影响布局,则需要倒回去重新渲染。就会导致第3步占用的时间过长,直接影响到了第4步的显示。

这里有一个规范,建议顺序大致如下:

1、定位属性:

position、display、float、left、top、right、bottom、overflow、clear、z-index

2、自身属性:

width、height、padding、border、margin、background

3、文字样式:

font-family、font-size、font-style、font-weight、font-varient、color

4、文本属性:

text-align、vertical-align、text-wrap、text-transform、text-indent、text-decoration、letter-spacing、word-spacing、white-space、text-overflow

5、CSS3 中新增属性:

content、box-shadow、border-radius、transform

减少reflow对性能的影响的建议

  1. 不要一条一条地修改 DOM 的样式,预先定义好 class,然后修改 DOM 的 className
  2. 把 DOM 离线后修改,比如:先把 DOM 给 display:none (有一次 Reflow),然后你修改100次,然后再把它显示出来
  3. 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量
  4. 尽可能不要修改影响范围比较大的 DOM
  5. 为动画的元素使用绝对定位 absolute / fixed
  6. 不要使用 table 布局,可能很小的一个小改动会造成整个 table 的重新布局

PS:当然,我们需要知道这个规则就够了,剩下的可以交给一些插件去做,譬如
CSSLint(能用代码实现的,千万不要去浪费人力)

扩展

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

减少repaint对性能的影响的建议

  1. 不要一条一条地修改 DOM 的样式。可以先定义好 css 的 class,然后修改 DOM 的 className。
  2. 不要把 DOM 结点的属性值放在一个循环里当成循环里的变量。
  3. 为动画的 HTML 元件使用 fixed 或 absoult 的 position,那么修改他们的 CSS 是不会 reflow 的。
  4. 千万不要使用 table 布局。因为可能很小的一个小改动会造成整个 table 的重新布局。(table及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性,通常要花2~3倍于同等元素的时间。这也是为什么我们要避免使用table做布局的一个原因。)
  5. 不要在布局信息改变的时候做查询(会导致渲染队列强制刷新)
  6. 用translate替代top改变
  7. 用opacity替代visibility(在独立图层下优化重绘)
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。