长列表网页置信大多数开发者都遇到过,在DOM元素过多的状况下,浏览器渲染会很慢,十分影响用户体验前端培训。
因而咱们会常常采纳虚构滚动、分页、上拉加载更多等不同的形式来进行优化,这些形式的思维都是一样的,都是只渲染可见区域,等用户须要时再加载更多的内容。而以上的形式无论哪种,都须要写大量的js或者css逻辑去实现。
而当初,咱们多了一种形式——content-visibility。只须要一行CSS代码,就能够实现可见网页只加载可见区域内容,使网页的渲染性能失去数倍的晋升!
介绍
content-visibility是一个css属性,它管制一个元素是否出现其内容,能让用户潜在地管制元素的出现。用户能够应用它跳过元素的出现(包含布局和绘制),直到用户须要为止,让页面的初始渲染失去极大的晋升。
value
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倍!而且随着元素内容变简单,晋升的性能会有更显著的回升。
再从下图的dom构造变动中也能够看到,当card未呈现在屏幕可见区域内是,其内容(::before等动画)在元素呈现在可见成果时才呈现:
缺点
兼容性
content-visibility是chrome85往年新增的个性,所以目前兼容性还不高,然而置信兼容性的问题在不久的未来会失去解决。目前兼容性如下:
局部元素导致浏览器渲染出问题
问题
当元素的局部内容如<img />标签这种,元素的高度是有图片内容决定的,因而在这种状况下,如果应用content-visibility,则可见视图外的img初始未渲染,高度为0,随着滚动条向下滑动,页面高度减少,会导致滚动条的滚动有问题。
<html>
<head>
<title>content-visibility</title><style type="text/css"> .card { margin-bottom: 10px; content-visibility: auto; }</style>
</head>
<body>
<div class="card"> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1057266467,784420394&fm=26&gp=0.jpg" alt="小狗" /> <!-- ... --> <!-- 此处省略n个card内容 --> <!-- ... --> <img src="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1057266467,784420394&fm=26&gp=0.jpg" alt="小狗" /></div>
</body>
</html>
解决思路
解决此问题,如果在已知元素高度的状况下,能够应用contains-intrinsic-size属性,为下面的card增加:contains-intrinsic-size:312px;,这会给内容附一个初始高度值。(如果高度不固定也能够附一个大抵的初始高度值,会使滚动条问题绝对缩小)。
批改代码如下:
<style type="text/css"> .card { margin-bottom: 10px; content-visibility: auto; contain-intrinsic-size: 312px; // 增加此行 }</style>
再次看滚动条就没有问题了:
总结
content-visibility是一个十分实用的CSS属性,通过一行CSS能够代替虚构滚动、上拉加载更多等多种长列表渲染优化形式。
尽管其兼容性当初不是很好,然而置信不久的未来这并不是问题。当初来看是局部场景下它对浏览器的滚动条影响问题,如果你的列表项高度雷同,那么能够通过contain-intrinsic-size来设置一个初始高度解决。如果列表项高度不固定而又非常重视用户的滚动条体验,那么不倡议应用此属性。当然了,这一css属性进去的工夫并不是太长,尽管它的欠缺,这一问题或者在未来也可能失去解决。