css渲染机制、优先级以及效率准则的那些事

Study · 2014-04-22 · 284 人浏览

前端人员几乎每天都要跟页面打交道,所以正常情况下你迟早还是要了解那些HTML和CSS等的一些渲染机制。一来是为了装逼你的专业技能,二来的确是可以提升各种效率,最终的结果就是你可以收获更多的银子。

最终决定浏览器表现出来的页面效果的差异是由浏览器渲染引擎 Rendering Engine(也叫做排版引擎),也就是我们通常所说的“浏览器内核”,负责解析网页语法(如HTML、CSS、JavaScript)并渲染、展示的结果。相同的代码在不同的浏览器呈现出来的效果不一样,那么就很有可能是不同的浏览器内核导致的。

加载页面时浏览器的具体工作流程是:

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

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

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

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

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

注意了:css引擎查找样式表,对每条规则都按从右到左的顺序去匹配(其实你也可以理解为按最后一条规则为准)。

四种选择器:ID、class、tag和通用符(*)的渲染速度差不多就是从快到慢的。

然后在这个渲染原理的指导下,我们就可以更规范更高效的写出我们的代码了。

比如:在CSS书写过程中,总结出如下性能提升的方案:

  • 1、避免使用通配规则。

如 *{} 计算次数惊人!只对需要用到的元素进行选择

PS:后来又看到了一篇对性能测试的文章反驳对性能的影响,使得理论和实际表现似乎有差异。文章出子丸子,点击链接查看

  • 2、尽量少的去对标签进行选择,而是用class。

如:#nav li{},可以为li加上nav_item的类名,如下选择.nav_item{}

  • 3、不要去用标签限定ID或者类选择符。

如:ul#nav,应该简化为#nav

  • 4、尽量少的去使用后代选择器,降低选择器的权重值

后代选择器的开销是最高的,尽量将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每一个标签元素

  • 5、考虑继承

了解哪些属性是可以通过继承而来的,然后避免对这些属性重复指定规则
但说到底,CSS性能这东西对于小的项目来讲可能真的是微乎其微的东西,提升可能也不是很明显,但对于大型的项目肯定是有帮助的。而且一个好的CSS书写习惯和方式能够帮助我们更加严谨的要求自己。

关于优先级这个问题

一般情况下,优先级如下:

(外部样式)External style sheet <(内部样式)Internal style sheet <(内联样式)Inline style

选择器的优先权,确切的说应该是权重值,如:

1、内联样式表的权值最高 1000

2、ID选择器的权值为 100

3、Class类选择器的权值为 10

4、HTML标签选择器的权值为 1

利用选择器的权值进行计算比较,示例如下:

<html>
 <head>
 <style type="text/css">
 #red_id p {
 /* 权值 = 100+1=101 */
 color:#f00; /* 红色 */
 }
 #red_id .red em {
 /* 权值 = 100+10+1=111 */
 color:#00F; /* 蓝色 */
 }
 #red_id p span em {
 /* 权值 = 100+1+1+1=103 */
 color:#FF0;/*黄色*/
 }
 </style>
 </head>
 <body>
 <div id="red_id">
 <p class="red">red<span><em>em red</em></span>
 </p>
 </div>
 </body>
</html>

结果: 标签内的数据显示为蓝色。

CSS 优先级法则:

1、选择器都有一个权值,权值越大越优先

2、当权值相等时,后出现的样式表设置要优于先出现的样式表设置

3、创作者的规则高于浏览者:即网页编写者设置的CSS样式的优先权高于浏览器所设置的样式

4、继承的CSS样式不如后来指定的CSS样式

5、在同一组属性设置中标有“!important”规则的优先级最大。

关于效率准则的那些事

我觉得这个东西,你要辩证的看。还有因为这个更多的是理念性的东西,所以我就不直接写了。直接上某个大神的几篇文章地址,仅供参考!

精简高效的CSS命名准则/方法:http://www.zhangxinxu.com/wordpress/?p=1098

去除冗余 – 精简您的CSS样式代码:http://www.zhangxinxu.com/wordpress/?p=629

CSS页面重构之“门派”之分:http://www.zhangxinxu.com/wordpress/?p=1022

CSS reset的重新审视 – 避免样式重置:http://www.zhangxinxu.com/wordpress/?p=758

CSS样式分离之再分离:http://www.zhangxinxu.com/wordpress/?p=916

最后附一份谷歌代码风格规范,大部分赞同,但是有些许部分在实际情况中还不是很适合。

E文版本的,但是应该不影响你们看代码风格的:http://google-styleguide.googlecode.com/svn/trunk/htmlcssguide.xml

https://developers.google.com/speed/docs/best-practices/rendering?hl=EN

网易NEC更好的css解决方案,我也喜欢:http://nec.netease.com/

PS:
其实现代浏览器对css的优化都做的很好了,以前关注的一些优化现在都再慢慢的被忽略掉了。因为给我的感觉是,css优化性能这块差异性是越来越小了,甚至很多人都直接不再css优化了。不过还是那句话,常规的该优化的还是得优化的,语意化很重要,然后css层级嵌套不要太深即可吧。

css
Theme Jasmine