这里首先想到的是:您使用的渲染引擎有多聪明?
这听起来很笼统,但在质疑 CSS 渲染/选择的效率时非常重要。例如,假设您的 CSS 文件中的第一条规则是:
.class1 {
/*make elements with "class1" look fancy*/
}
因此,当一个非常基本的引擎看到这一点时(并且因为这是第一条规则),它会查看 DOM 中的每个元素,并检查每个元素中是否存在class1
。更好的引擎可能会将类名映射到 DOM 元素列表,并使用哈希表之类的东西来进行有效查找。
.class1.class2 {
/*make elements with both "class1" and "class2" look extra fancy*/
}
我们的示例“基本引擎”将重新访问 DOM 中的每个元素以查找这两个类。更聪明的引擎会将 DOM 中的元素数量与 class 进行比较,并n('class1')
取最小值;假设那是,然后传递所有元素并寻找也有的元素。n('class2')
n(str)
str
class1
class1
class2
无论如何,现代引擎都很聪明(比上面讨论的例子更聪明),闪亮的新处理器每秒可以执行数百万(数千万)次操作。您的 DOM 中不太可能有数百万个元素,因此任何选择 ( O(n)
) 的最坏情况下的性能无论如何都不会太差。
更新:
为了获得一些实际实用的说明性证据,我决定做一些测试。首先,为了了解我们在实际应用程序中平均可以看到多少个 DOM 元素,我们来看看一些流行网站的网页有多少个元素:
Facebook: ~1900 个元素(在我的个人主页上测试过)。
谷歌:~340 个元素(在主页上测试,没有搜索结果)。
谷歌: ~950 个元素(在搜索结果页面上测试)。
雅虎!:~1400 个元素(在主页上测试)。
Stackoverflow: ~680 个元素(在问题页面上测试)。
AOL: ~1060 个元素(在主页上测试)。
维基百科: ~6000 个元素,其中 2420 个不是spans
或anchors
(在维基百科关于 Glee的文章中测试)。
Twitter:约 270 个元素(在主页上测试)。
总结这些,我们平均得到约 1500 个元素。现在是时候进行一些测试了。对于每个测试,我生成了 1500divs
个(嵌套在其他divs
一些测试中),每个测试都有适当的属性,具体取决于测试。
测试
样式和元素都是使用 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
具有 a 的 a 中title
,并且嵌套在div
带有 class的 a 中.chatpage
。用于选择消息是正确.chatpage div[title]
的,但在效率方面也是不好的做法。给所有消息一个类并使用该类选择它们更简单、更易于维护和更有效。
花哨的单行结论:
任何在“是的,这个 CSS 有意义”范围内的东西都可以。