本文是《Even Faster Web Sites: Performance Best Practices for Web Developers (Paperback)》的最後一章。上篇帖子《Performance Impact of CSS Selectors》(中文版)最後提出了一段假設:
對大多數網站而言,優化CSS選擇器活得的性能提升很小,不值得去計較。有些配合Javascript交互的CSS規則會明顯的拖慢頁面。這是應該關注的焦點。所以我開始關注現實中影響頁面性能的CSS樣式相關的小問題。
我收到了很多反饋。David Hyatt的文章《Writing EfficIEnt CSS for use in the Mozilla UI》披露:
樣式系統渲染一條規則是從最右邊開始之後依次向左移動。在你的小子樹(subtree)持續檢測的時候,樣式系統將繼續向左側移動直到它不匹配CSS規則或匹配錯誤。
由此得出,我們優化工作的重點應該是:匹配大量頁面元素的最右側的CSS選擇器。我上篇博文測試的CSS選擇器看起來很費性能,但是按這條新觀點審視,我們發覺這其實不值得擔心,比如:
DIV DIV DIV P A.class0007 {}
這個選擇器有5層,看起來很復雜,但是我們來看最右側的選擇器 A.class0007 ,我們發現,在整個頁面中需要浏覽器逆向匹配的只有一個元素。
優化CSS選擇器的關鍵點在於最右側的選擇器,也叫做key selector (巧合?)。有一個更昂貴的選擇器
A.class0007 * {}
盡管這個選擇器看起來更簡單,但對浏覽器匹配而言更昂貴。因為浏覽器要從右至左,開始後要檢查匹配 * 的所有元素。這意味著浏覽器會嘗試匹配頁面中的所有元素。下圖為普通選擇器與先前的後代選擇器加載時間的對比:
它清晰的反映出一個匹配很多元素的key selector會嚴重的拖慢頁面。其他可能會大量增加浏覽器工作的key selector包括:
A.class0007 DIV {}
#id0007 > A {}
.class0007 [href] {}
DIV:first-child {}
不是所有的CSS選擇器傷害性能,盡管看起來如此。CSS選擇器的關鍵點在於泛匹配的key selector。這對於含有大量DOM元素、CSS規則,更高 reflow 的Web 2.0應用更加重要。