日期:2014-05-17  浏览次数:20632 次

CSS样式规则优化
最近思维里经常浮现的一些词是“优化”,“Web优化”,“Javascript优化”等等涉及到前端开发的优化技术。正如这个单词表达的“Front-end”,止于前端,一个网站产品最终的体现就是在浏览器内显示的界面上,这是从用户的角度来看待一个web产品的价值的一个方面,当然了,实用性和趣味性也是非常重要的一个方面。本人是搞前端开发,当然就会从浏览器的角度去思考问题。说到优化,前面的几篇文章谈到了一个方面的优化“提高页面的加载速度”,这个方面所涉及到的技术也是非常广阔的。下面来谈谈在css方面的一个优化。

以前写css的时候,都没有想到过css还能够优化,来加快页面样式的渲染速度。今天写这篇文章的思路是从这个问题开始的“浏览器是怎么解析css样式规则并且渲染页面elements的样式的?”,这个问题我也跟别人讨论过,终没结果,之后google出了一片mozilla的关于编写高效的css的文章,受益匪浅。揭开了我上面提到的那个问题,它是这样表述的:
引用
The style system matches a rule by starting with the rightmost selector and moving to the left through the rule's selectors. As long as your little subtree continues to check out, the style system will continue moving to the left until it either matches the rule or bails out because of a mismatch.
Your first line of defense is the rule filtering that occurs based on the type of the key selector. The purpose of this categorization is to filter out rules so that you don't even have to waste time trying to match them. This is the key to dramatically increasing performance. The fewer rules that you even have to check for a given element, the faster style resolution will be. As an example, if your element has an ID, then only ID rules that match your element's ID will be checked. Only class rules for a class found on your element will be checked. Only tag rules that match your tag will be checked. Universal rules will always be checked.


上面的两端En文道出了浏览器解析css样式规则的机制:浏览器样式系统是从右到左来解析每一条css样式规则,并且从HTML文档中查询elements,并且渲染样式的。En文不太好,翻译全部有些难度,请见谅。从这个机制出发,就可以体会到很多优化css的selectors优化方法了:

1.避免使用全局的css样式规则。顾名思义,全局的selectors渲染了全部的Elements的样式,耗费的时间和内存就比普通的selectors翻倍的了。
比如:
[hidden="true"] { } /* A universal rule */
* { } /* A universal rule */
tree > [collapsed="true"] { } /* A universal rule */

2.不要在ID的selectors里添加tag前缀。因为ID是唯一的,因此没必要再加个前缀tag来增加css的解析级数了。
BAD - button#backButton { }
BAD - .menu-left#newMenuIcon { }
GOOD - #backButton { }
GOOD - #newMenuIcon { }

3.不要在class的selectors里添加tag前缀,原因跟第二条是一样的。
BAD - treecell.indented { }
GOOD - .treecell-indented { }
BEST - .hierarchy-deep { }

4.尽量简短你的selectors编写。这条是根据css的解析机制的金科玉律,为了减少解析级数。对于一些需要编写比较长的selectors来渲染指定的Elements的,能通过class或者ID等简短编写的,尽量使用这种方式。比如:
BAD - treeitem[mailfolder="true"] > treerow > treecell { }
BAD - treehead treerow treecell { }
BAD - treeitem[IsImapServer="true"] > treerow > .tree-folderpane-icon { }
GOOD - .treecell-mailfolder { }

5.多使用继承。css中也有继承,合理的使用继承可以减少css样式规则的编写量,这是其中的一个方面。比如:
BAD - #bookmarkMenuItem > .menu-left { list-style-image: url(blah); }
GOOD - #bookmarkMenuItem { list-style-image: url(blah); }

6.整合一些图片为一个图片。这种应用在navigation或者一些背景切换上都是能很好的优化页面的加载速度以及css的渲染速度的,在我的那篇《小译“”》里就提到了最小化HTTP Request请求的优化方案。这在css里也是一样的,css也可以通过background-image等等方式来加载图片。将一些可以整合为一个图片的众多图片整合起来,就会将Http Request减少到只有一个,这在其他的css selectors如果用到了这种图片,也可以直接从缓存里读取,而无需又发起一个Http Request来加载。

这篇文章不算是翻译吧,因为它并不是从原文了一字一字翻译过来的,都是自己理解的情况下口语化的表述出来了,有错误在所难免,还请见谅和加以勘误。