这里首先需要考虑的是,你正在使用的
渲染引擎有多聪明?
尽管听起来很普通,但这在质疑CSS渲染/选择的效率时非常重要。例如,假设你的CSS文件中的第一条规则是:
.class1 {
}
因此,当一个非常基本的引擎看到这个(因为这是第一个规则),它会查看您DOM中的每个元素,并检查每个元素中是否存在
class1
。更好的引擎可能会将类名映射到DOM元素列表,并使用类似哈希表的东西进行高效查找。
.class1.class2 {
}
"Our example 'basic engine' would search through each element in the DOM to find both classes. A more sophisticated engine would compare
n('class1')
and
n('class2')
, where
n(str)
represents the number of elements in the DOM with the class
str
, and select the minimum value. If
class1
is the minimum, then it will look for all elements with
class1
and search for elements that also have
class2
.
"However, modern engines are much more advanced than the example mentioned above, and new processors can perform millions (even tens of millions) of operations per second. It's highly unlikely that you have millions of elements in your DOM, so the worst-case performance for any selection (
O(n)
) won't be too bad."
更新:
为了获得一些实际的实证证据,我决定进行一些测试。首先,为了了解我们在真实应用中可以看到多少平均DOM元素,请看一下一些受欢迎的网站页面有多少元素:
Facebook:约1900个元素(在我的个人主页上测试)
Google:约340个元素(在主页上测试,没有搜索结果)
Google:约950个元素(在搜索结果页面上测试)
Yahoo!:约1400个元素(在主页上测试)
Stackoverflow:约680个元素(在问题页面上测试)
AOL:约1060个元素(在主页上测试)
Wikipedia:约6000个元素,其中2420个不是或标签(在关于Glee的维基百科文章上测试)
Twitter:约270个元素(在主页上测试)
总结一下,我们得到了大约1500个元素的平均值。现在是时候进行一些测试了。对于每个测试,我生成了1500个divs
(对于某些测试嵌套在其他divs
中),每个divs
具有与测试相关的适当属性。
测试
样式和元素都是使用PHP生成的。我已经上传了所使用的PHP文件,并创建了一个索引,以便其他人可以在本地进行测试:小链接。
结果:
每个测试在三个浏览器上进行 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
类似的实验:
显然,其他人已经做过类似的实验;这个实验还有一些有用的统计数据:小链接。
总之:
如果你不在意节省渲染时间(1毫秒=0.001秒),那么不要太费心。另一方面,避免使用复杂的选择器来选择大量的元素是一个好的习惯,因为这可能会产生一些明显的差异(就像我们从上面的测试结果中看到的那样)。所有常见的CSS选择器在现代浏览器中都相当快。
假设你正在构建一个聊天页面,你想为所有消息设置样式。你知道每条消息都在具有title
的 div
中,并嵌套在一个带有类 .chatpage
的 div
中。使用.chatpage div[title]
来选择消息是正确的,但从效率角度来看,这也是不好的做法。将所有消息都赋予一个类并使用该类进行选择更简单、更易维护,也更有效率。
华丽的一句话结论:
只要在“是的,这个CSS有意义”的范围内,任何东西都是可以的。
position: fixed
就是一个CSS不应该被重复使用的例子。并不是说我主张做这样的事情。 - Michał Górnybody
的三个子元素和其他内容,则任何选择器都不应该导致浏览器崩溃甚至冻结。 - BoltClock