从浏览器的渲染原理讲CSS性能

平时咱们几乎天天都在和浏览器打交道,写出来的页面颇有可能在不一样的浏览器下显示的不同。苦逼的前端攻城师们为了兼容各个浏览器而不断地 去测试和调试,还在脑子中记下各类遇到的BUG及解决方案,而咱们好像并无去主动地关注和了解下浏览器的工做原理。若是咱们对此作一点了解,我想在项目 过程当中就能够根据它有效的避免一些问题以及对页面性能作出相应的改进。今天咱们主要根据浏览器的渲染原理对CSS的书写性能作一点改进(固然还有JS本篇 文章暂不考虑,后面的文章会作介绍),下面让咱们一块儿来揭开浏览器的渲染原理这一神秘的面纱吧:php

最终决定浏览器表现出来的页面效果的差别是:渲染引擎 Rendering Engine(也叫作排版引擎),也就是咱们一般所说的“浏览器内核”,负责解析网页语法(如HTML、JavaScript)并渲染、展现网页。相同的代码在不一样的浏览器呈现出来的效果不同,那么就颇有多是不一样的浏览器内核致使的。css

咱们来看一下加载页面时浏览器的具体工做流程(图一):前端

(图一)后端

一、解析HTML以重建DOM树(Parsing HTML to construct the DOM tree ):渲染引擎开始解析HTML文档,转换树中的标签到DOM节点,它被称为“内容树”。浏览器

二、构建渲染树(Render tree construction):解析CSS(包括外部CSS文件和样式元素),根据CSS选择器计算出节点的样式,建立另外一个树 —- 渲染树。dom

三、布局渲染树(Layout of the render tree): 从根节点递归调用,计算每个元素的大小、位置等,给每一个节点所应该出如今屏幕上的精确坐标。布局

四、绘制渲染树(Painting the render tree) : 遍历渲染树,每一个节点将使用UI后端层来绘制。性能

主要的流程就是:构建一个dom树,页面要显示的各元素都会建立到这个dom树当中,每当一个新元素加入到这个dom树当中,浏览器便会经过css引擎查遍css样式表,找到符合该元素的样式规则应用到这个元素上。测试

注意了:css引擎查找样式表,对每条规则都按从右到左的顺序去匹配。 看以下规则:spa

1
#nav  li {}

看起来很快,实际上很慢,尽管这让人有点费解#_#。咱们中的大多数人,尤为是那些从左到右阅读的人,可能猜测浏览器也是执行从左到右匹配规则的, 所以会推测这条规则的开销并不高。在脑海中,咱们想象浏览器会像这样工做:找到惟一的ID为nav的元素,而后把这个样式应用到直系子元素的li元素上。 咱们知道有一个ID为nav的元素,而且它只有几个Li子元素,因此这个CSS选择符应该至关高效。

事实上,CSS选择符是从右到左进行匹配的。了解这方面的知识后,咱们知道这个以前看似高效地规则实际开销至关高,浏览器必须遍历页面上每一个li元素并肯定其父元素的id是否为nav。

1
*{}

额,这种方法我刚写CSS的也写过,却不知这种效率是差到极点的作法,由于*通配符将匹配全部元素,因此浏览器必须去遍历每个元素,这样的计算次数多是上万次!

1
ul#nav{} ul.nav{}

在页面中一个指定的ID只能对应一个元素,因此没有必要添加额外的限定符,并且这会使它更低效。同时也不要用具体的标签限定类选择符,而是要根据实际的状况对类名进行扩展。例如把ul.nav改为.main_nav更好。

1
ul li li li .nav_item{}

对于这样的选择器,以前也写过,最后本身也数不过来有多少后代选择器了,何不用一个类来关联最后的标签元素,如.extra_navitem,这样只须要匹配class为extra_navitem的元素,效率明显提高了

对此,在CSS书写过程当中,总结出以下性能提高的方案:

  1. 避免使用通配规则      如    *{} 计算次数惊人!只对须要用到的元素进行选择

  2. 尽可能少的去对标签进行选择,而是用class     如:#nav li{},能够为li加上nav_item的类名,以下选择.nav_item{}

  3. 不要去用标签限定ID或者类选择符   如:ul#nav,应该简化为#nav

  4. 尽可能少的去使用后代选择器,下降选择器的权重值  后代选择器的开销是最高的,尽可能将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每个标签元素

  5. 考虑继承 了解哪些属性是能够经过继承而来的,而后避免对这些属性重复指定规则

选用高效的选择符,能够减小页面的渲染时间,从而有效的提高用户体验(页面越快,用户固然越喜欢^_^),你能够看一下CSS selectors Test,这个实验的重点是评估复杂选择符和简单选择符的开销。也许当你想让渲染速度最高效时,你可能会给每一个独立的标签配置一个ID,而后用这些ID写样式。那的确会超级快,也超级荒唐!这样的结果是语义极差,后期的维护难到了极点。

但说到底,CSS性能这东西对于小的项目来说可能真的是微乎其微的东西,提高可能也不是很明显,但对于大型的项目确定是有帮助的。并且一个好的CSS书写习惯和方式可以帮助咱们更加严谨的要求本身。

相关文章
相关标签/搜索