这个问题旨在为前端开发人员提供一个有用的资源,部分CSS可能实际上对设备性能有重大影响,以及哪些设备/浏览器或引擎可能受到影响。这不是一个关于如何编写优雅或可维护的CSS的问题,它纯粹关于性能(虽然希望这里写的内容可以通知更多关于最佳实践的一般文章)。
现有证据
Google和Mozilla有关编写高效CSS的书面指南,CSSLint’s set of rules包括:
Avoid selectors that look like regular expressions
..
don’t use the complex equality operators to avoid performance penalties
但没有一个提供任何证据(我可以找到)的影响这些都有。
一个css-tricks.com article on efficient CSS认为(在概述了效率最佳实践的负载),我们不应该牺牲语义或可维护性的高效CSS这些天。
一个perfection kills blog post建议border-radius和Box-shadow渲染的数量级比简单的CSS规则慢。这在Opera的引擎中是非常重要的,但在Webkit中是微不足道的。此外,smashing magazine CSS benchmark发现CSS3显示规则的渲染时间不显着,并且比使用图像渲染等效效果快得多。
知道你的手机tested various mobile browsers,发现他们都渲染CSS3同样不显着地快(在12毫秒),但它看起来像他们在PC上的测试,所以我们不能推断手机设备如何执行与CSS3一般。
有are many articles在互联网上如何编写高效的CSS。然而,我还没有找到任何全面的证据,严重考虑CSS实际上对一个网站的渲染时间或快节奏有重大影响。
背景
我为这个问题提供了赏金,尝试使用SO的社区权力来创建一个有用的研究资源。
解决方法
那么,通用的声音,当质疑CSS渲染/选择的效率时,很重要。例如,假设CSS文件中的第一个规则是:
.class1 { /*make elements with "class1" look fancy*/ }
因此,当一个非常基本的引擎看到(因为这是第一条规则),它去看看你的DOM中的每一个元素,并检查每个class1的存在。更好的引擎可能会将类名映射到DOM元素列表,并使用类似于hashtable的方式来进行有效的查找。
.class1.class2 { /*make elements with both "class1" and "class2" look extra fancy*/ }
我们的例子“基本引擎”将去重新审视DOM中的每个元素寻找两个类。 cleverer引擎将比较n(‘class1’)和n(‘class2’),其中n(str)是DOM中的元素数量与类str,并取最小值;假设是class1,然后传递所有带有class1的元素,寻找具有class2的元素。
在任何情况下,现代引擎是聪明的(比上面讨论的例子更聪明),闪亮的新处理器可以做一百万(数千万)的操作。你的DOM中有几百万个元素是不太可能的,所以任何选择(O(n))的最坏情况的性能不会太糟糕。
更新:为了得到一些实际的说明性证明,我决定做一些测试。首先,要了解平均有多少DOM元素可以在现实世界的应用程序中看到,让我们来看看一些热门网站的网页有多少元素:
Facebook:〜1900元素(在我的个人主页上测试)。
Google:〜340个元素(在主页上测试,没有搜索结果)。
Google:约950个元素(在搜索结果页上测试)。
Yahoo!:〜1400元素(在主页上测试)。
Stackoverflow:〜680元素(在问题页面上测试)。
AOL:〜1060个元素(在主页上测试)。
维基百科:〜6000元素,其中2420不是跨度或锚点(在Wikipedia article about Glee测试)。
Twitter:〜270个元素(在主页上测试)。
总而言之,我们得到的平均值约为1500元素。现在是时候做一些测试。对于每个测试,我生成1500 divs(嵌套在一些其他div中的一些测试),每个具有适当的属性,取决于测试。
测试
样式和元素都是使用PHP生成的。我已经上传了我使用的PHP,并创建了一个索引,以便其他人可以在本地测试:little link。
结果:
每个测试在三个浏览器(平均时间报告)执行5次:Firefox 15.0(A),Chrome 19.0.1084.1(B),Internet Explorer 8(C):
A B C 1500 class selectors (.classname) 35ms 100ms 35ms 1500 class selectors,more specific (div.classname) 36ms 110ms 37ms 1500 class selectors,even more specific (div div.classname) 40ms 115ms 40ms 1500 id selectors (#id) 35ms 99ms 35ms 1500 id selectors,more specific (div#id) 35ms 105ms 38ms 1500 id selectors,even more specific (div div#id) 40ms 110ms 39ms 1500 class selectors,with attribute (.class[title="ttl"]) 45ms 400ms 2000ms 1500 class selectors,more complex attribute (.class[title~="ttl"]) 45ms 1050ms 2200ms
类似实验:
显然其他人进行了类似的实验;这个也有一些有用的统计数据:little link。
底线:除非你关心在渲染时保存几个毫秒(1ms = 0.001s),不要打扰这个太多的想法。另一方面,避免使用复杂选择器来选择元素的大子集是一个好的习惯,因为这可以产生一些显着的差异(从上面的测试结果可以看出)。所有常见的CSS选择器在现代浏览器中速度相当快。
假设您正在创建聊天页面,并且要对所有邮件设置样式。你知道每个消息都在一个div,它有一个标题,并嵌套在一个div。类.chatpage。使用.chatpage div [title]选择消息是正确的,但它也是不良的做法效率。给所有消息一个类并使用该类选择它们更简单,更可维护和更高效。
奇怪的一线结论:
任何在“是的,这CSS有意义”的限制是可以的。