Chrome 52 中的 CSS 防護機制

Paul Lewis

TL;DR

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

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

其中包含幾個值,其語法如下:

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

本功能內建於 Chrome 52 以上版本和 Opera 40 以上版本 (而且 Firefox 提供公開支援),因此請迫不及待地告訴我們您的使用體驗!

包含屬性

無論是製作網頁應用程式還是複雜的網站,主要都是面臨一項重大成效挑戰,而是限制樣式、版面配置和繪製效果。DOM 的「完全」在運算工作中,通常屬於「涵蓋範圍」;也就是說,嘗試在網頁應用程式中獨立使用「檢視畫面」的做法,可能就很難判斷:在 DOM 的某個部分進行變更可能會影響其他部分,因而無法判斷瀏覽器究竟應該位於或超出範圍為何。

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

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

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

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

然後將新元素附加至一個檢視畫面,藉此觸發樣式、版面配置和繪製功能:

    <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 資源,由開發人員負責控管相關項目:遏制

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

  • layout
  • paint
  • size
  • style

每個值都可讓您限制瀏覽器所需的轉譯工作量。現在來逐一詳細介紹

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

版面配置遏制可能是抑制的「最大」,以及 contain: paint

版面配置通常限定文件範圍,因此會依照 DOM 的大小縮放,因此如果您變更元素的 left 屬性,就必須檢查 DOM 中的每個元素。

如果啟用隔離功能,可將元素數量減少為只有少部分 (而非整份文件),因此可為瀏覽器節省大量不必要的工作,並大幅改善效能。

塗料 (含:顏料)

範圍顏料是遏制的另一項非常實用的好處。使用塗料基本上會裁切有問題的元素,但也有一些其他副作用:

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

大小 (含尺寸)

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

大小控制是一種皮帶和大括號測量方式,可確保您不會仰賴子項元素調整大小,但這本身並未帶來太多效能助益。

樣式 (包含:樣式)

變更元素樣式後, DOM 樹狀結構會備份哪些元素,並不容易。例如 CSS 計數器,就代表變更子項的計數器會影響文件中其他地方使用相同名稱的計數器值。設定 contain: style 後,樣式變更就不會被套用在所屬元素後方。

明確來說,contain: style「無法」提供的是限定範圍樣式,如來自 Shadow DOM 一樣;這裡的封裝只是用來限制樣式變更時才會考慮的樹狀結構部分,而「不是」在宣告樣式時加以限制。

嚴格和內容隔斷

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

  • contain: strict 表示與 contain: size layout paint 相同
  • contain: content 表示與 contain: layout paint 相同

如果您事先知道元素的大小 (或想保留其尺寸),使用嚴格範圍限制是不錯的做法,但請注意,如果您宣告的嚴格包含「沒有」尺寸,由於隱含的大小包含,因此該元素可能會顯示為 0 x 0 像素的方塊。

另一方面,「內容包含」功能可大幅改善範圍,但不需要事先瞭解或指定元素的尺寸。

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

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

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