我承认在过去的设计开发中很少考虑这样的思想。。。问题是一个CSS写的是否高效,取决于浏览器能够以多快的速度去完成渲染。
这貌似是一个浏览器提供商应该关心的问题(加载越快,当然浏览器用户用着也就更开心)。Mozilla有一篇文章https://developer.mozilla.org/en/Writing_Efficient_CSS”>about best practices. Google也经常为了给web和浏览器提速进行一些重大举措。这里还有另外一篇相关的文章https://code.google.com/speed/page-speed/docs/rendering.html。
想让我们把这些宏伟的想法抛在一边,来讨论一下具体的实践措施去优化CSS的渲染速度。
从右到左
第一件,也是最重要的一件事是去了解浏览器是怎么去阅读CSS选择器的:那就是“从右向左”读,意思是,比如这一段选择器“ul > li a[title=”home”]”,首先被解释出来的是“a[title=”home”]”,这部分也最终被作为这段选择器的“主选择器”。
ID选择器最高效,遍历(通用)选择器的效率最低
有四种形式的“主选择器”:ID、Class、tag、和遍历,现在排出的顺序就是按照渲染效率从高到低的进行的:
#main-navigation { } /* ID (最快) */ body.home #page-wrap { } /* ID */ .main-navigation { } /* Class */ ul li a.current { } /* Class * ul { } /* Tag */ ul li a { } /* Tag */ * { } /* Universal (最慢) */ #content [title=’home’] /* Universal */
如果我们在实际编写中考虑了这种“从左到右”的思想,我们就会觉得下面的选择器效率不是很高:
#main-nav > li { } /* 比想象要慢很多 */
虽然这听上去和我们的直觉不尽相同:我们觉得浏览器会很快地先找到这个ID然后同样很快地去找到他的子元素li。但事实上,这个子元素li速度要更快些。
不要给ID选择器加标签修饰!
ID是独一无二的,所以他们根本不需要再用一个标签名修饰。这样做只会让这个选择器效率降低。
最好也不要这样修饰Class,除非是在你不能避免的时候。Class不是第一无二的,所以理论上你可以把一个class名用在多个不同的元素上,像li.first,你也许真的需要去用标签修饰,不过这种情况并不常见,总而言之,不要这样。
层次选择器是最差的
David Hyatt说”层次选择器是CSS中最‘贵’的选择器。尤其当这个选择器在一个标签或通用选择器里面。”
换句话说,像下面这段选择器就是一个灾难:
html body ul li a { }
考虑好为什么你需要这个选择器
考虑一下这个:
#main-navigation li a { font-family: Georgia, Serif; }
“字体”在级联菜单中定义并不需要精确到最下级(除非你这个选择器的目的纯粹是为了改变字体)。像下面这样就高效得多:
#main-navigation { font-family: Georgia, Serif; }
CSS3的效能
“CSS3最悲哀的事实:如果你关心页面的表现,你根本不应该去用它”
比如,CSS3的选择器(e.g.:nth-child) 能够帮我们很好帮我们找到目标元素并保持标记的可读性和简洁性。但是,事实上,这些选择器会消耗更大的浏览器资源。
那我们到底该不该用CSS3呢?让我们来考虑一些实用性的问题。
实用性问题
Mozilla的那片文章从字面上看已经过去十年了。那时电脑速度比现在要慢很多。所以我今天讲的东西用在十年前更有意义。现在很少有人再去讨论“渲染效率”这个话题了,因为对于现在的浏览器这已经不是最主要的问题。
我们今天讨论这个话题,主要目的是让你了解浏览器有渲染效率这个事实,而且提供给你一种方法去优化你的CSS。