通过跳过屏幕外的内容渲染来缩短初始加载工夫
在 Chromium 85 中,content-visibility 属性可能是在进步页面加载性能方面最具影响力的新 CSS 属性之一。因为 content-visibility 可跳过不在屏幕上的内容渲染,包含布局和渲染,直到真正须要布局渲染的时候为止。所以利用它能够使初始用户加载速度更快,还能与屏幕上的内容进行更快的交互。
在下面这个 demo 中,应用 content-visibility: auto 属性可使分块的内容区域的初始加载性能进步 7 倍。请浏览上面更多信息。
浏览器反对
content-visibility 依赖于 css Containement Spec 中的原语(primitives)。尽管截止到目前只有 Chromium 85 中反对 content-visibility 属性(and deemed “worth prototyping” for Firefox),然而大多数古代浏览器均反对 Containement Spec。
CSS Containment
CSS Containment 标准的次要目标是,在页面渲染的过程中通过疏忽文档中的某些子树来进步页面的渲染性能。
当容器的内容发生变化时,浏览器思考到其余元素可能也会发生变化,于是就会去查看页面中所有的元素。始终以来浏览器都是这么做的,大家都司空见惯了。然而从另一方面说,开发者很分明以后批改的元素是否独立、是否影响其余元素。因而如果开发者能把这个信息通过 CSS 通知浏览器,那么浏览器就不须要再去思考其余元素了,这将是十分完满的事件。CSS Containment 模块中提供的 contain 属性就为咱们提供了这种能力。
css contain 有四个属性能够以空格宰割的形式组合在一起,而每一个属性又能够独自可用。
- size: 示意元素盒子的大小是独立于其内容,也就是说在计算该元素盒子大小的时候是会疏忽其子元素
- layout: 该值示意元素的外部布局不受内部的任何影响,同时该元素以及其内容也不会影响到下级
- style: 申明那些同时会影响这个元素和其子孙元素的属性,都在这个元素的蕴含范畴内
- paint: 申明这个元素的子孙节点不会在它边缘外显示。如果一个元素在视窗外或因其余起因导致不可见,则同样保障它的子孙节点不会被显示。
设置 content-visibility 跳过渲染
个别很难分明明确应用哪个 contain 属性,因为只有在指定了适当的值后,浏览器才开始优化。你能够应用这些值来验证最无效的办法,也能够应用 content-visibility 的 CSS 属性来主动利用所用的容量。content-visibility 可确保你以开发人员最小的老本来取得浏览器最大的性能晋升。
content-visibility 属性承受多个值,然而 auto 是可立刻进步性能的属性。一个具备 content-visibility: auto 属性的元素能够取得布局、款式和绘制的限度(区域)。如果该元素不在屏幕上(并且与用户无关,则相干元素将是在其子树中具备焦点或已抉择的元素),它也会取得大小限度(containment)(并且进行绘制和对其内容进行命中测试)。
这意味着什么呢?简而言之,如果元素不在屏幕上,这不会渲染其后辈。浏览器在不思考元素任何内容的状况下确定元素的大小,在此处则跳过大多数渲染(例如元素子树的款式和布局)。
当元素靠近视口时,浏览器不再减少大小限度,而是开始绘制并命中测试元素的内容。这使得渲染工作可能及时被用户看到。
例子:游览博客
travel_blog.mp4
在此示例中,咱们将旅行博客的基线设置在右侧,并将 content-visibility:auto 利用于左侧的分块区域。结果显示,在初始页面加载时,渲染工夫从 232ms 变为 30ms。
个别游览博客都会蕴含一些图片和一些描述性的文字故事。这是典型浏览器导航到旅行博客时产生的状况:
- 页面的局部内容以及任何所需的资源都从网络下载
- 浏览器的款式和布局页面的所有内容,而无需思考该内容是否对用户可见
- 浏览器返回到步骤 1,直到下载了所有页面和资源
在步骤 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. */}
留神:随着内容移入和移出可见性,它将依据须要开始和进行绘制。然而,这并不意味着浏览器将不得不一次又一次地渲染和从新渲染雷同的内容,因为在可能的状况下会保留渲染工作。
应用 contain-intrinsic-size 指定元素的天然大小
为了实现 content-visibility 的潜在益处,浏览器须要利用大小限度,以确保内容的出现后果不会被任何形式影响元素的大小。这意味着该元素将布局为如同是空的。如果元素没有在惯例块布局中指定的高度,则其高度为 0。
这可能不是现实的,因为滚动条的大小会发生变化,这取决于每个具备非零高度的内容。
值得庆幸的是,CSS 提供了另一个属性 contains-intrinsic-size,如果元素受大小限度影响,它能够无效地指定元素的天然大小。在咱们的示例中,咱们将其设置为 1000px,作为对这些局部的高度和宽度的预计。
这意味着它如同有一个“外在大小”尺寸的子项一样进行布局,从而确保未调整大小的 div 依然占据空间。contains-intrinsic-size 用作占位符大小,而不是出现的内容。
暗藏内容设置 content-visibility: hidden
如果想要利用缓存绘制状态的长处,使内容不显示在屏幕上而又不绘制它怎么办?应用 content-visibility: hidden.
content-visibility:hidden 属性为您提供未渲染内容和缓存的渲染状态的所有雷同益处,如 content-visibility:auto does off-screen。然而,与 auto 不同,它不会主动开始在屏幕上渲染。
这给了您更多的控制权,使您能够暗藏元素的内容并稍后疾速勾销暗藏它们。
将其与其余暗藏元素内容的常见形式进行比拟:
- display:none:暗藏元素并毁坏其渲染状态。这意味着勾销暗藏元素与渲染具备雷同内容的新元素一样低廉。
- visibility:hidden:暗藏元素并放弃其渲染状态。这并不能真正从文档中删除该元素,因为它(及其子树)仍占据页面上的几何空间,并且依然能够单击。它也能够在须要时随时更新渲染状态,即便暗藏也是如此。
另一方面,content-visibility:hidden 暗藏元素,同时保留其出现状态,因而,如果须要进行任何更改,则仅在再次显示元素时才会产生更改(即 content-visibility:hidden 属性已移除)。
content-visibility:hidden 的一些很好用例:实现高级虚构滚动条和测量布局。
论断:
content-visibility 和 CSS Containment Spec 意味着您的 CSS 文件将取得一些令人兴奋的性能晋升。无关这些属性的更多信息,请参考:
- The CSS Containment Spec
- MDN Docs on CSS Containment
- CSSWG Drafts
翻译原文:https://web.dev/content-visibility/
参考内容:
1、https://www.infoq.cn/article/lBECNlBbgd81U01aQUMF?utm_source=related_read&utm_medium=article
2、https://www.zcfy.cc/article/css-containment-in-chrome-52-web-updates-google-developers-873.html
3、https://developer.mozilla.org/zh-CN/docs/Web/CSS/contain
原翻译地址带视频:[https://www.yuque.com/17biu/sacpix/dvfeii
]