1. 程式人生 > >優化CSS選擇符

優化CSS選擇符

        CSS選擇符對效能的影響源於瀏覽器匹配選擇符和文件元素時所消耗的時間,前端攻城獅們可以通過編寫更高效的選擇符來控制匹配耗時,實現高效率選擇符首先要理解選擇符是如何匹配的。

1 CSS匹配規則:最右邊優先

           看下面這條規則:

 #toc > LI {
      font-weight:bold;
 }

對於我們大多數有從左到右閱讀習慣的人,可能自然而然的認為瀏覽器也是執行從左到右的匹配規則,因此會認為這條規則的開銷並不高。我們普遍認為瀏覽器會這樣工作:找到唯一的id為toc的元素,然後繼續尋找這個元素的直系子元素LI,把樣式應用到LI上。我們知道只有一個id為toc的元素,並且它只有幾個LI子元素,所以這個CSS選擇符應該相當高效。然鵝,瀏覽器並沒有按照我們的套路走,事實上,

CSS選擇符是按照從右到左的順序進行匹配的。瞭解這個特性後,我們知道這個之前看似高效的規則實際上開銷相當高,瀏覽器必須遍歷頁面上每個LI元素並確定其父元素的id是否為toc。後代選擇符的效率更糟:

#toc  A{
     color:#fff;
}

在這個選擇符中,瀏覽器會檢查整個文件中的每個連結,然而,瀏覽器並不僅僅檢查每個連結的父元素,甚至還要遍歷文件樹去查詢id為toc的祖先元素。如果被檢查的連結不是toc元素的後代,那麼瀏覽器就要向上一級遍歷直到文件的根節點。在看一個例子:

DIV DIV DIV P A.class0007{
    color:red;
}

一眼看上去,這似乎是一個開銷很高的選擇符,它是一個要匹配5級祖先元素的後代選擇符,然而瀏覽器會從右到左進行匹配,所以這個後代選擇符的速度和一個更簡單的類選擇符差不多。最右邊的引數也叫關鍵選擇符,它對瀏覽器執行的工作量起主要影響。在本例中,關鍵選擇符是A.class0007,頁面中只有一個元素匹配這個關鍵選擇符,所以這個選擇符的匹配時間是極少的。

           樣式系統從最右邊的選擇符開始向左匹配規則。只要當前選擇符的左邊還有其它選擇符,樣式系統就會繼續向左移動,直到找到和規則匹配的元素,或者因為不匹配而退出。

2 編寫高效的CSS選擇符

           理解了選擇符的右邊優先原則,我們就可以從另一個角度看CSS選擇符,並將其調整得更高效。下面是一些編寫高效選擇符的指南:

  • 避免使用通配規則

除了傳統意義上的通配選擇符之外,Hyatt也把相鄰兄弟選擇符、子選擇符、後代選擇符和屬性選擇符都歸納到“通配規則”分類下。他推薦僅使用ID、類和標籤選擇符。

  • 不要限定ID選擇符

在頁面中一個指定ID只能對應一個元素,所以沒有必要新增額外的限定符。例如:

DIV#toc 是沒有必要的,應該簡化為#toc。

  • 不要限定類選擇符

不要用具體的標籤限定類選擇符,而是根據實際情況對型別進行擴充套件。例如:

把LI.chapter 改成 .li-chapter。

  • 讓規則越具體越好

不要試圖編寫像OL LI A這樣的長選擇符,最好是建立一個像.list-anchor一樣的類,並把它新增到適當的元素上。

  • 避免使用後代選擇符

處理後代選擇符的開銷是最高的,而通常使用子選擇符也可以得到想要的結果,並且更高效。遵循下一條指南就更好了,這樣連子選擇符也可以避免使用了。

  • 避免使用標籤—子選擇符

如果有像#toc  > LI  > A 這樣的基於標籤的子選擇符,那麼應該使用一個類來關聯每個標籤元素,比如.toc-anchor。

  • 質疑子選擇符的所有用途

再次提醒攻城獅們所有使用子選擇符的地方,儘可能用具體的類取代它們。

  • 依靠繼承

瞭解哪些屬性可以通過繼承而來,然後避免對這些屬性重複指定規則。例如,對列表元素而不是每個列表項元素指定list-style-image.

3 認識迴流時間

         上面的例子都是關於CSS選擇符在載入匹配上的影響,對於CSS的效能,還有個問題需要我們考慮:當用戶和頁面進行互動時,瀏覽器應用樣式和佈局元素所消耗的時間,即迴流時間。

         當使用JavaScript修改DOM元素樣式的某些屬性時會觸發迴流。例如修改一個元素的border、padding等等。迴流並不需要涉及頁面上的所有元素,僅僅對那些受迴流影響的元素進行重新佈局。如果修改了一個文件的body或其他一些有很多後代元素的padding屬性,那麼迴流的開銷就會相當高。

         迴流需要重新應用CSS規則,瀏覽器必須再次匹配所有的CSS選擇符。如果CSS選擇符是低效的,迴流可能消耗的時間就會多到引起使用者的注意。因此,杜絕低效的CSS選擇符的影響,不僅要考慮頁面載入時間,也要考慮使用者和網頁互動時樣式的表現。