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: layout)

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

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

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

繪製 (包含:繪製)

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

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

大小 (包含:大小)

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

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

樣式 (contain: style)

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

為求明確,contain: style 不會提供您從 Shadow DOM 取得的範圍樣式;這裡的封存功能僅會限制樹狀結構的哪些部分在樣式變異時會受到考量,不會在樣式宣告時受到考量。

嚴格和內容限制

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

  • contain: strictcontain: size layout paint 的意思相同
  • contain: contentcontain: layout paint 的意思相同

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

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

在兩者中,contain: content 是您應預設使用的選項。當 contain: content 無法滿足您的需求時,您應將嚴格限制視為更安全的備用方案。

請告訴我們使用狀況

容器是向瀏覽器指出您想在網頁中保留哪些內容的絕佳方法。請在 Chrome 52 以上版本中試用,並告訴我們使用體驗!