Chrome 52 中的 CSS 防護機制

Paul Lewis

TL;DR

新的 CSS Containment 屬性可讓開發人員限制瀏覽器的樣式、版面配置和繪製作業範圍。

CSS 包含性。變更前:版面配置需要 59.6 毫秒。之後:版面配置耗時 0.05 毫秒

它有幾個值,因此語法如下:

    contain: none | strict | content | [ size || layout || style || paint ]

這項功能已在 Chrome 52 以上版本和 Opera 40 以上版本中推出 (Firefox 也提供公開支援),歡迎試用並告訴我們使用情形!

contain 屬性

製作網頁應用程式或複雜網站時,限制樣式、版面配置和繪製效果,是重要的效能挑戰。通常,整個 DOM 都會視為運算作業的「範圍內」,這可能表示在網路應用程式中嘗試使用自給自足的「檢視畫面」可能會變得棘手:DOM 某部分的變更可能會影響其他部分,而且無法告知瀏覽器哪些項目應在或不應在範圍內。

舉例來說,假設 DOM 的部分內容如下所示:

    <section class="view">
      Home
    </section>

    <section class="view">
      About
    </section>

    <section class="view">
      Contact
    </section>

您會在一個 View 中附加新元素,這會觸發樣式、版面配置和繪製:

    <section class="view">
      Home
    </section>

    <section class="view">
      About
      <div class="newly-added-element">Check me out!</div>
    </section>

    <section class="view">
      Contact
    </section>

但在此例中,「整個 DOM」的有效性就是指樣式、版面配置和繪製計算一律必須考量「所有元素」,無論元素是否已變更。DOM 越大,所需的運算工作就越多,也就是說,您很可能會讓應用程式無法回應使用者輸入內容。

好消息是,現代瀏覽器會自動限制樣式、版面配置和繪圖作業的範圍,因此您不必採取任何行動,就能加快速度。

不過,更棒的消息是,我們推出了新的 CSS 屬性,可將範圍控制權交給開發人員:Containment

CSS Containment 是新的屬性,其中包含關鍵字 contain,支援四個值:

  • layout
  • paint
  • size
  • style

您可以透過這些值限制瀏覽器需要執行的轉譯工作量。讓我們進一步瞭解每個值。

版面配置 (包含:版面配置)

版面配置容器化功能可能是容器化功能的最大優點,與 contain: paint 一樣。

版面配置通常是文件範圍,因此會根據 DOM 的大小進行縮放,因此如果您變更元素的 left 屬性,可能就需要檢查 DOM 中的每個元素。

在此啟用容器功能,可能會將元素數量減少到只有少數幾個,而不是整份文件,這樣瀏覽器就不必執行大量不必要的工作,也能大幅提升效能。

塗料 (含:顏料)

範圍設定是另一個非常實用的容器功能。繪圖封存功能本質上會裁剪問題元素,但也有一些其他副作用:

  • 它可做為絕對位置和固定位置元素的容器區塊。也就是說,任何子項會根據含有 contain: paint 的元素 (而非文件) 等其他父項元素來定位。
  • 也就是堆疊的背景這表示 z-index 之類的項目會對元素產生影響,而子項會根據新結構定義進行堆疊。
  • 視覺輔助也就是說,如果您有包含繪圖容器的區塊層級元素,系統會將其視為新的獨立版面配置環境。也就是說,元素外部的版面配置通常不會影響包含元素的子項。

大小 (含尺寸)

contain: size 的意思是,元素的子項不會影響父項的大小,且系統會使用推斷或宣告的尺寸。因此,如果您設定 contain: size,但並未指定元素的尺寸 (無論是直接或透過彈性屬性指定),還是以 0 x 0 像素顯示!

大小限制功能其實是一種雙重保障措施,可確保您不會依賴子項元素來設定大小,但本身並不會帶來太多效能優勢。

樣式 (contain: style)

變更元素樣式對 DOM 樹狀結構的影響,很難預測會如何影響樹狀結構。舉例來說,如果您使用 CSS 計數器,在子項中變更計數器,可能會影響文件中其他地方使用相同名稱的計數器值。設定 contain: style 後,樣式變更不會傳遞至包含元素以外的元素。

為求明確,contain: style 不會提供您從 Shadow DOM 取得的範圍樣式;這裡的容器僅會限制樹狀結構中在樣式變異時要考量的部分,不會在宣告時限制。

嚴格和內容限制

你也可以結合關鍵字,例如 contain: layout paint,這樣就能只將這些行為套用至元素。但 contain 也支援兩個額外的值:

  • contain: strictcontain: size layout paint 的意思相同
  • contain: content 表示與 contain: layout paint 相同

如果您事先知道元素的大小 (或希望保留其尺寸),使用嚴格限制的容器會很實用。不過請注意,如果您在宣告嚴格限制的容器時不指定尺寸,由於系統會隱含大小限制,元素可能會顯示為 0 像素 x 0 像素的方塊。

另一方面,內容容器可大幅改善範圍,但您不必事先知道或指定元素的尺寸。

在兩者中,contain: content 是您應預設使用的選項。當 contain: content 無法滿足您的需求時,您應該將嚴格控制視為收穫更強的事。

也請與我們分享你滿意的成果

容器很適合用來向瀏覽器指明您打算在網頁中隔離的內容。歡迎在 Chrome 52 以上版本中試用這項功能,並與我們分享你的使用體驗!