`content-visibility`:增强呈现效果的新CSS属性

2020-08-05 15:45:01

在Chrome85中推出的content-visibility属性可能是提高页面加载性能的最有效的新CSS属性之一。内容可见性使用户代理可以跳过元素的渲染工作,包括布局和绘画,直到需要为止。因为会跳过呈现,所以如果很大一部分内容在屏幕外,则利用Content-Visibility属性可以更快地加载初始用户。它还允许与屏幕上的内容进行更快的交互。相当整洁。

内容可见性依赖于CSS ContainmentSpec中的原语。虽然目前只有Chrome85支持内容可见性(对于Firefox来说,这也被认为是值得进行原型开发的),但大多数现代浏览器都支持包容规范(Containment Spec)。

CSS包容的关键和总体目标是通过提供可预测的DOM子树与页面其余部分的隔离来提高Web内容的渲染性能。

基本上,开发人员可以告诉浏览器页面的哪些部分被封装为一组内容,从而允许浏览器对内容进行推理,而无需考虑子树之外的状态。知道哪些内容位(子树)包含隔离内容意味着浏览器可以为页面呈现做出优化决策。

CSS包含有四种类型,每种类型都是CONTAIN CSS属性的潜在值,它们可以组合在一个空格分隔的值列表中:

大小:元素上的大小限制确保该元素的框可以在不需要检查其后代的情况下被取出。这意味着如果我们只需要元素的大小,我们可能会跳过后代的布局。

布局:布局包容是指后代不影响页面上其他框的外部布局。这允许我们潜在地跳过子代的播放,如果我们只想布局其他框的话。

样式:样式包含确保不仅影响其后代的属性不会转义元素(例如计数器)。这允许我们潜在地跳过子代的样式计算,如果所有我们想要的都是计算其他元素的样式。

油漆:油漆容器确保包含盒子的后代不会显示在其边界之外。任何东西都不能明显地溢出元素,如果元素在屏幕外或以其他方式不可见,那么它的子代也将不可见。这样,如果元素在屏幕外,我们可能会跳过绘制后代。

可能很难确定使用哪些包含值,因为浏览器优化可能只有在指定适当的集合时才会生效。您可以使用这些值来查看哪种方法效果最好,或者可以使用另一个名为Content-Visibility的CSS属性自动应用nesidedcontainment。内容可见性确保您作为开发人员以最少的努力获得浏览器所能提供的最大性能收益。

Content-Visibility属性接受多个值,但AUTO是提供即时性能改进的一个。具有内容可见性的元素:自动获得布局、样式和绘画包容度。如果元素在屏幕外(否则与用户相关的元素是那些在其子树中有焦点或选择的元素),它也会获得大小控制(并且停止绘制和命中测试其内容)。

这是什么意思?简而言之,如果元素在屏幕外,则不会呈现其后代。浏览器在不考虑元素的任何内容的情况下确定元素的大小,到此为止。大多数呈现,比如元素的子树的样式和布局,都会被跳过。

当元素接近视口时,浏览器不再添加大小娱乐,并开始绘制和点击测试元素的内容。这使得渲染工作可以及时完成,用户可以看到。

旅游博客通常包含一组带有几张图片和一些描述性文字的故事。以下是一个典型的浏览器在导航到旅游博客时会发生的情况:

浏览器设置页面所有内容的样式和布局,而不考虑内容是否对用户可见。

浏览器返回到步骤1,直到下载完所有页面和资源。

在步骤2中,浏览器处理所有内容,查找可能已更改的内容。它会更新任何新元素的样式和布局,以及可能因新更新而改变的元素。这是渲染工作。这需要时间。

现在考虑一下,如果在博客中的每个单独的故事上放置content-visibility:auto,会发生什么情况。一般循环是相同的:浏览器下载并呈现页面的大块。但是,不同之处在于它在步骤2中所做的工作量。

有了内容可见性,它将对用户当前可见的所有内容(它们在屏幕上)设置样式并进行布局。但是,当处理完全在屏幕外的文章时,浏览器将跳过渲染工作,仅对元素框本身进行样式和布局。

加载此页面的性能就像它包含完整的屏幕上故事和每个屏幕外故事的空框一样。这样的性能要好得多,预计可以从加载的渲染成本中降低50%或更多。在我们的示例中,我们看到渲染时间从232ms提高到30ms。这使性能提升了7倍。

您需要做什么工作才能获得这些好处?首先,我们将内容分成几个部分:

请注意,当内容移入和移出可见性时,它将根据需要开始呈现和停止呈现。然而,这并不意味着浏览器将不得不一遍又一遍地呈现相同的内容,因为在可能的情况下会保存呈现工作。

为了实现内容可见性的潜在好处,浏览器需要应用大小控制,以确保内容的呈现结果不会以任何方式影响元素的大小。这意味着元素的布局将好像是空的。如果元素没有在常规块布局中指定的高度,则它的高度将为0。

这可能并不理想,因为滚动条的大小会发生变化,这依赖于每个具有非零高度的故事。

值得庆幸的是,CSS提供了另一个属性,CONTAIN-INTERNAL-SIZE,如果元素受到大小控制的影响,它可以有效地指定元素的自然大小。在我们的示例中,我们将其设置为1000px作为截面高度和宽度的估计值。

这意味着它的布局就像它只有一个固有尺寸的子项,确保您的未调整大小的div仍然占用空间。CONTAINE-INTERNAL-SIZE用作占位符大小,而不是呈现内容。

如果您希望保持内容不呈现,而不管内容是否显示在屏幕上,同时利用缓存呈现状态的好处,该怎么办呢?输入:内容-可见性:隐藏。

Content-Visibility:Hidden属性为您提供了与Content-Visibility:auto在屏幕外提供的所有未呈现内容和缓存呈现状态相同的好处。不过,与AUTO不同的是,它不会在屏幕上自动启动Torender。

这给了您更多的控制权,允许您隐藏元素的内容,并在以后快速将其取消隐藏。

DISPLAY:NONE:隐藏元素并破坏其呈现状态。这意味着取消隐藏元素的代价与使用相同内容呈现新元素的代价一样高。

可见性:隐藏:隐藏元素并保持其呈现状态。这并不能真正从文档中删除该元素,因为它(以及它的子树)仍然占据页面上的几何空间,并且仍然可以点击。它还会在需要时随时更新渲染状态,甚至在隐藏时也是如此。

Content-Visibility:另一方面,Hidden在保留元素呈现状态的同时隐藏元素,因此,如果需要进行任何更改,它们仅在元素再次显示时才会发生(即,Content-Visibility:Hidden属性被移除)。

内容可见性:隐藏的一些很好的用例是在实现高级虚拟滚动和测量布局时。

内容可见性和CSS包含规范意味着一些令人兴奋的性能提升将直接应用到您的CSS文件中。有关这些属性的更多信息,请查看: