长列表网页置信大多数开发者都遇到过,在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属性进去的工夫并不是太长,尽管它的欠缺,这一问题或者在未来也可能失去解决。