經過跳過屏幕外的內容渲染來縮短初始加載時間css
在Chromium 85中,content-visibility屬性多是在提升頁面加載性能方面最具影響力的新CSS屬性之一。由於content-visibility可跳過不在屏幕上的內容渲染,包括佈局和渲染,直到真正須要佈局渲染的時候爲止。因此利用它可使初始用戶加載速度更快,還能與屏幕上的內容進行更快的交互。html
在上面這個demo中,使用content-visibility: auto屬性可以使分塊的內容區域的初始加載性能提升7倍。請閱讀下面更多信息。git
content-visibility依賴於css Containement Spec中的原語(primitives)。雖然截止到目前只有Chromium 85中支持content-visibility屬性(and deemed "worth prototyping" for Firefox),可是大多數現代瀏覽器均支持Containement Spec。github
CSS Containment 規範的主要目的是,在頁面渲染的過程當中經過忽略文檔中的某些子樹來提升頁面的渲染性能。web
當容器的內容發生變化時,瀏覽器考慮到其餘元素可能也會發生變化,因而就會去檢查頁面中全部的元素。一直以來瀏覽器都是這麼作的,你們都習覺得常了。可是從另外一方面說,開發者很清楚當前修改的元素是否獨立、是否影響其餘元素。所以若是開發者能把這個信息經過 CSS 告訴瀏覽器,那麼瀏覽器就不須要再去考慮其餘元素了,這將是很是完美的事情。CSS Containment 模塊中提供的 contain 屬性就爲咱們提供了這種能力。chrome
css contain 有四個屬性能夠以空格分割的方式組合在一塊兒,而每個屬性又能夠單獨可用。瀏覽器
通常很難清楚明白使用哪一個contain屬性,由於只有在指定了適當的值後,瀏覽器纔開始優化。你可使用這些值來驗證最有效的方法,也可使用content-visibility的CSS屬性來自動應用所用的容量。content-visibility可確保你以開發人員最小的成原本得到瀏覽器最大的性能提高。緩存
content-visibility屬性接受多個值,可是auto是可當即提升性能的屬性。一個具備content-visibility: auto屬性的元素能夠得到佈局、樣式和繪製的限制(區域)。若是該元素不在屏幕上(而且與用戶無關,則相關元素將是在其子樹中具備焦點或已選擇的元素),它也會得到大小限制(containment)(而且中止繪製和對其內容進行命中測試)。網絡
這意味着什麼呢?簡而言之,若是元素不在屏幕上,這不會渲染其後代。瀏覽器在不考慮元素任何內容的狀況下肯定元素的大小,在此處則跳過大多數渲染(例如元素子樹的樣式和佈局)。app
當元素接近視口時,瀏覽器再也不增長大小限制,而是開始繪製並命中測試元素的內容。這使得渲染工做可以及時被用戶看到。
例子:旅遊博客
在此示例中,咱們將旅行博客的基線設置在右側,並將content-visibility:auto應用於左側的分塊區域。 結果顯示,在初始頁面加載時,渲染時間從232ms變爲30ms。
通常旅遊博客都會包含一些圖片和一些描述性的文字故事。這是典型瀏覽器導航到旅行博客時發生的狀況:
在步驟2中,瀏覽器處理全部內容以查找可能已更改的內容。 它會更新任何新元素的樣式和佈局,以及因爲新更新而可能發生移動的元素。 這是渲染工做。 這須要時間。
demo: https://codepen.io/una/pen/rNxEWLo
如今考慮一下,若是將content-visibility: auto設置在博客上每一個單獨的故事上會發生什麼呢?通常是相同的循環:瀏覽器下載並呈現大塊的內容。可是,不一樣之處則是步驟2的工做量。
藉助content-visibility,他將設置樣式和佈局用戶當前可見的全部內容(他們在屏幕可視區域內)。可是,當處理徹底不在屏幕上的內容使,瀏覽器將跳過渲染工做,僅樣式化和佈局元素框自己。
加載頁面的性能好像它只包含完整的屏幕上的內容以及每一個非屏幕上的內容的空白框。這樣的效果看起來要好的多,其能夠將加載的渲染成本下降50%或更多。在咱們的示例中,咱們看到渲染的時間從232ms提高到了30ms,性能提高了7倍。
爲了得到這些好處,您須要作什麼工做? 首先,咱們將內容分紅幾部分:
Example of chunking content into sections with the story
class applied, to receive content-visibility: auto
. See Demo on Codepen
而後,咱們將如下樣式規則應用於這些部分:
.story { content-visibility: auto; contain-intrinsic-size: 1000px; /* Explained in the next section. */ }
注意:隨着內容移入和移出可見性,它將根據須要開始和中止繪製。 可是,這並不意味着瀏覽器將不得不一次又一次地渲染和從新渲染相同的內容,由於在可能的狀況下會保存渲染工做。
爲了實現content-visibility的潛在好處,瀏覽器須要應用大小限制,以確保內容的呈現結果不會被任何方式影響元素的大小。 這意味着該元素將佈局爲好像是空的。 若是元素沒有在常規塊佈局中指定的高度,則其高度爲0。
這可能不是理想的,由於滾動條的大小會發生變化,這取決於每一個具備非零高度的內容。
值得慶幸的是,CSS提供了另外一個屬性contains-intrinsic-size,若是元素受大小限制影響,它能夠有效地指定元素的天然大小。 在咱們的示例中,咱們將其設置爲1000px,做爲對這些部分的高度和寬度的估計。
這意味着它好像有一個「內在大小」尺寸的子項同樣進行佈局,從而確保未調整大小的div仍然佔據空間。 contains-intrinsic-size用做佔位符大小,而不是呈現的內容。
若是想要利用緩存繪製狀態的優勢,使內容不顯示在屏幕上而又不繪製它怎麼辦?使用content-visibility: hidden.
content-visibility:hidden屬性爲您提供未渲染內容和緩存的渲染狀態的全部相同好處,如content-visibility:auto does off-screen。 可是,與auto不一樣,它不會自動開始在屏幕上渲染。
這給了您更多的控制權,使您能夠隱藏元素的內容並稍後快速取消隱藏它們。
將其與其餘隱藏元素內容的常見方式進行比較:
另外一方面,content-visibility:hidden隱藏元素,同時保留其呈現狀態,所以,若是須要進行任何更改,則僅在再次顯示元素時纔會發生更改(即content-visibility:hidden屬性已移除)。
content-visibility:hidden的一些很好用例:實現高級虛擬滾動條和測量佈局。
結論:
content-visibility和CSS Containment Spec意味着您的CSS文件將得到一些使人興奮的性能提高。 有關這些屬性的更多信息,請參考:
翻譯原文:https://web.dev/content-visibility/
參考內容:
一、https://www.infoq.cn/article/lBECNlBbgd81U01aQUMF?utm_source=related_read&utm_medium=article
二、https://www.zcfy.cc/article/css-containment-in-chrome-52-web-updates-google-developers-873.html