Image placeholder

content-visibility: 可提高页面渲染性能的 CSS 属性

Image placeholder
F2EX 2021-07-06

content-visibility CSS属性用于控制元素是否完全呈现其内容,基本上,它能够跳过元素的渲染工作(包括布局和绘制),直到需要它为止—这使得初始页面加载速度更快。

content-visibility 属性可能是用于提高页面加载性能的最有影响力的 CSS 属性之一。content-visibility 使浏览器能够跳过元素的渲染工作,包括布局和绘制,直到需要它为止。由于跳过了渲染,如果你的大部分内容超出屏幕外,利用 content-visibility 属性会使初始用户加载速度更快。这使得与屏幕上的内容进行更快的交互,并且使页面看起来更加整洁。

语法

/* 关键字值  */
content-visibility: visible;
content-visibility: hidden;
content-visibility: auto;

/* 全局值 */
content-visibility: inherit;
content-visibility: initial;
content-visibility: revert;
content-visibility: unset;

visible

没有效果。元素的内容按正常布局和呈现。

hidden

该元素跳过其内容。跳过的内容不能被访问,不会被呈现也无法选择。这类似于display: none

auto

该元素渲染相关的布局、样式和绘制。如果不相关,它也会跳过其内容。与 hidden 不同,跳过的内容仍然可获得焦点。

将 content-visibility: auto 应用于分块的内容区域可在初始加载时将渲染性能提升 7 倍

与 contain 一起使用

contain CSS 属性允许元素及其内容尽可能独立于文档树的其余部分。这允许浏览器为 DOM 的有限区域而不是整个页面重新计算布局、样式、绘制、大小或它们的任意组合,从而带来明显的性能优势。

.hidden {
  content-visibility: hidden;
  /* 当隐藏时,我们希望元素有一个 0x500px 的大小  */
  contain-intrinsic-size: 0 500px;
}
.visible {
  content-visibility: visible;
  /* 这是为了在 .hidden 和 .visible 之间切换时避免布局偏移 */
  contain: style layout paint;
}
<div class=hidden>...</div>
<div class=visible>...</div>
<div class=hidden>...</div>
<div class=hidden>...</div>

可能很难确定 contain 要使用哪些包含值,因为浏览器优化可能只有在指定了适当的集合时才会启动。你可以使用这些值( style 或者 layout )来查看什么最有效,或者你可以使用 content-visibility 来自动应用所需的包含。content-visibility 确保你作为开发人员以最少的工作量获得浏览器可以提供的最大性能提升。

content-visibility 属性接受多个值,但 auto 是提供即时性能改进的值。具有内容可见性的元素:自动获得布局、样式和绘制包含。如果元素在屏幕外(并且与用户无关——相关元素是在其子级中具有焦点或选择的元素),它也会获得大小控制(并且停止绘制和命中其内容)。

简而言之,如果元素在屏幕外,则不会呈现其后代。浏览器在不考虑任何内容的情况下确定元素的大小,然后停在那里。大多数渲染,例如元素子级的样式和布局都被跳过了。当元素接近视口时,浏览器不再添加尺寸限制并开始绘制和加载元素的内容。这使得渲染工作能够及时完成,以便用户看到。

关于可访问性的说明

content-visibility: auto 的特性之一是屏幕外的内容在文档对象模型中仍然可用,因此,可访问性(与可见性visibility: hidden 不同)。这意味着,可以在页面上搜索并导航到该内容,而无需等待它加载或牺牲渲染性能。

另一方面,样式 display:nonevisibility: hidden 也会在屏幕外等待渲染,因为浏览器在进入视口之前不会渲染这些样式。为了防止这些在可访问性中可见,可能会导致的混乱,请务必同时添加 aria-hidden="true"

演示

此示例中,我们将右侧标签的旅游博客设为基线,并将 content-visibility: auto 应用于左侧标签的分块区域。结果显示初始页面加载时的渲染时间从 232 毫秒到 30 毫秒。

本文中演示摘自 web.dev/content-visibility/


2021-07-06