content-visibility是一個css屬性,它控制一個元素是否呈現其內容,能讓用戶潛在地控制元素的呈現。用戶可以使用它跳過元素的呈現(包括布局和繪制),直到用戶需要為止,讓頁面的初始渲染得到極大的提升。
content-visibility屬性有三個可選值:
- visible: 默認值。對布局和呈現不會產生什么影響。
- hidden: 元素跳過其內容的呈現。用戶代理功能(例如,在頁面中查找,按Tab鍵順序導航等)不可訪問已跳過的內容,也不能選擇或聚焦。類似於對其內容設置了display: none屬性。
- auto: 對於用戶可見區域的元素,瀏覽器會正常渲染其內容;對於不可見區域的元素,瀏覽器會暫時跳過其內容的呈現,等到其處於用戶可見區域時,瀏覽器在渲染其內容。
效果對比:
使用前
如下代碼,在瀏覽器中簡單的使用100個卡片,並對其設置掃光效果動畫:
<html> <head> <title>content-visibility</title> <style type="text/css"> .card { position: relative; overflow: hidden; transition-duration: 0.3s; margin-bottom: 10px; width: 200px; height: 100px; background-color: #ffaa00; } .card:before { content: ''; position: absolute; left: -665px; top: -460px; width: 300px; height: 15px; background-color: rgba(255, 255, 255, 0.5); transform: rotate(-45deg); animation: searchLights 2s ease-in 0s infinite; } @keyframes searchLights { 0% { } 75% { left: -100px; top: 0; } 100% { left: 120px; top: 100px; } } </style> </head> <body> <div class="card"></div> <div class="card"></div> <!-- ... --> <!-- 此處省略97個<div class="card"></div> --> <!-- ... --> <div class="card"></div> </body> </html>
渲染效果
從chrome可以看出,渲染時間花費了1454ms:
使用后
在class為card中添加 content-visibility: auto;
.card { position: relative; overflow: hidden; transition-duration: 0.3s; margin-bottom: 10px; width: 200px; height: 100px; background-color: #ffaa00; content-visibility: auto; } .card:before { content: ''; // ...
渲染效果
可以明顯的看到,使用content-visibility: auto;
后渲染時間只需要381ms,性能提升了近4倍!而且隨着元素內容變復雜,提升的性能會有更明顯的上升。
兼容性
content-visibility是chrome85今年新增的特性,所以目前兼容性還不高,但是相信兼容性的問題在不久的將來會得到解決。目前兼容性如下:
部分元素導致瀏覽器渲染出問題
當元素的部分內容如<img />
標簽這種,元素的高度是有圖片內容決定的,因此在這種情況下,如果使用content-visibility
,則可見視圖外的img初始未渲染,高度為0,隨着滾動條向下滑動,頁面高度增加,會導致滾動條的滾動有問題。
解決此問題,如果在已知元素高度的情況下,可以使用contains-intrinsic-size
屬性,為上面的card添加:contains-intrinsic-size:312px;
,這會給內容附一個初始高度值。(如果高度不固定也可以附一個大致的初始高度值,會使滾動條問題相對減少)。
總結
content-visibility是一個非常實用的CSS屬性,通過一行CSS可以代替虛擬滾動、上拉加載更多等多種長列表渲染優化方式。
雖然其兼容性現在不是很好,但是相信不久的將來這並不是問題。現在來看是部分場景下它對瀏覽器的滾動條影響問題,如果你的列表項高度相同,那么可以通過contain-intrinsic-size
來設置一個初始高度解決。如果列表項高度不固定而又非常重視用戶的滾動條體驗,那么不建議使用此屬性。當然了,這一css屬性出來的時間並不是太長,雖然它的完善,這一問題或許在將來也能夠得到解決。