如何提升 CSS 选择器性能
CSS 选择器性能损耗来自?
CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,所以优化选择器的原则是应尽量避免使用消耗更多匹配时间的选择器。而在这之前我们需要了解CSS选择器匹配的机制, 如子选择器规则:
1 | header > a {font-weight:blod;} |
我们中的大多数人都是从左到右的阅读习惯,会习惯性的设定浏览器也是从左到右的方式进行匹配规则,推测这条规则的开销并不高。
我们会假设浏览器以这样的方式工作:寻找 id 为 header 的元素,然后将样式规则应用到直系子元素中的 a 元素上。我们知道文档中只有一个 id 为 header 的元素,并且它只有几个 a 元素的子节点,所以这个CSS选择器应该相当高效。
事实上,却恰恰相反,CSS选择器是从右到左进行规则匹配。了解这个机制后,例子中看似高效的选择器在实际中的匹配开销是很高的,浏览器必须遍历页面中所有的 a 元素并且确定其父元素的 id 是否为 header 。
如果把例子的子选择器改为后代选择器则会开销更多,在遍历页面中所有 a 元素后还需向其上级遍历直到根节点。
1 | header a {font-weight:blod;} |
.content * {color: red;}
1 |
|
#BAD
button backButton {…}
#BAD
.menu-left newMenuIcon {…}
#GOOD
backButton {…}
#GOOD
newMenuIcon {…}
1 | #### 3、避免使用标签限制 class 选择器 |
#BAD
treecell.indented {…}
#GOOD
.treecell-indented {…}
#BEST
.hierarchy-deep {…}
1 |
|
#BAD
treeitem[mailfolder=”true”] > treerow > treecell {…}
#GOOD
.treecell-mailfolder {…}
1 |
|
#BAD
treehead treerow treecell {…}
#BETTER, BUT STILL BAD
treehead > treerow > treecell {…}
#GOOD
.treecell-header {…}
1 |
|
#BAD
bookmarkMenuItem > .menu-left { list-style-image: url(blah) }
#GOOD
bookmarkMenuItem { list-style-image: url(blah) }
### 思考
作为一名前端工程师,应该具有「提升 CSS 选择器性能」的意识,但实际应用中,是否需要完全贯彻这些原则呢?这是一个探索「追求高性能」与「可维护性」两者平衡的问题。
对于「淘宝」,每个页面的 DOM 元素超过1000个以上的网站来说,通过限制 CSS 选择器,改善性能是具有实际意义的。但对于普通网站,我更倾向于保证「语义化」和「可维护性」的前提下,提升 CSS 选择器性能。
参考 「1」[Efficiently Rendering CSS][1] 「2」[Writing efficient CSS][2] 「3」[Performance Impact of CSS Selectors][3] 「4」[CSS Test Creator][4] 「5」[高性能CSS][5] 「6」[如何撰寫有效率的CSS選擇器][6]
[1]: http://css-tricks.com/efficiently-rendering-css/
[2]: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Writing_efficient_CSS?redirectlocale=en-US&redirectslug=Writing_Efficient_CSS
[3]: http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/
[4]: http://stevesouders.com/efws/css-selectors/csscreate.php?n=1000&sel=div+div+div+div+div+div+a&body=background%3A+%23CFD&ne=1000
[5]: http://www.alloyteam.com/2012/10/high-performance-css/
[6]: http://www.mrmu.com.tw/2011/10/11/writing-efficient-css-selectors/
The Why·Liam·Blog by WhyLiam is licensed under a Creative Commons BY-NC-ND 4.0 International License.
由WhyLiam创作并维护的Why·Liam·Blog采用创作共用保留署名-非商业-禁止演绎4.0国际许可证。
本文首发于Why·Liam·Blog (https://blog.naaln.com),版权所有,侵权必究。
本文永久链接:https://blog.naaln.com/2014/08/how-improve-performance-css-selectors/