延迟渲染繁重内容

Web 功能: content-visibility

内容丰富的网页(例如无限滚动、复杂的仪表板或密集的文章)可能会出现初始渲染缓慢和互动迟缓的问题。现代 Web 技术可让您推迟渲染不会立即显示的内容,从而在不破坏无障碍功能或用户预期的情况下显著提升性能。

为了优化渲染,您可以使用 CSS content-visibility 属性和 HTML hidden="until-found" 属性。虽然两者都有助于提升性能,但它们适用于不同的应用场景。

何时使用哪种工具

场景/示例 已应用功能 性能优势
1. 非首屏(延迟初始加载) content-visibility: auto 浏览器会自动卸载布局/绘制工作负载,直到容器滚动到接近视图的位置,从而保持标准网页加载速度顺畅。
2. 切换状态(快速切换视图) content-visibility: hidden 跳过隐藏 div 的布局计算,但保留样式包含状态,从而实现即时切换,而不会发生结构变化(优于 display: none)。
3. 可搜索和延迟(可折叠披露声明) hidden="until-found" 如需详细了解如何将渲染性能与页内查找搜索无障碍功能相结合,请参阅搜索隐藏的内容。

如何实现content-visibility: auto

选择屏幕外的内容

强制性要求:您必须仔细确定哪些元素会收到 content-visibility: auto。

  • 务必定位到严格位于初始首屏下方的大型独立布局块(例如无限信息流中的卡片项、尾随评论或底部较重的布局部分)。
  • 请勿将此属性应用于初始首屏视口中的元素。这样做会强制浏览器在渲染之前评估可见性边界,反而会延迟关键网页加载性能。
  • 务必定位具有深层或复杂内部 DOM 结构的元素,以最大限度地节省渲染成本。

实现步骤

  1. 强制性:确定在初始加载时确认位于屏幕外的重型部分。
  2. 强制性要求:对每个屏幕外元素应用 content-visibility: auto。
  3. 强制性:使用 contain-intrinsic-size 为每个元素提供估算的布局结构大小。

如何使用 contain-intrinsic-size

强制性:您必须将 content-visibility: auto 与 contain-intrinsic-size 配对。否则,浏览器会在元素离开屏幕时将其高度折叠为 0 像素,从而导致严重的布局偏移和滚动条跳动。

contain-intrinsic-size CSS 简写属性充当占位符尺寸。使用 auto 关键字可让浏览器在元素最终渲染后“记住”确切大小,如果元素再次离开屏幕,则使用该计算大小(而非占位符)。

示例代码

/* DO ONLY apply this class to items OUTSIDE the initial layout viewport */
.heavy-section-deferred {
  /* MANDATORY: Skips rendering calculations when off-screen */
  content-visibility: auto;
  
  /* Mandatory: Provide an estimated size to prevent layouts shifts.
    - 'auto' is optional and enables the browser to remember the actual size
      once rendered. It must be paired with a <length> value to be used for
      the first render.
    - 'none' tells the browser not to apply any intrinsic width to this element.
      It can be used for either the height or the width value.
    - '150px' is the estimated height of this element. This can be any valid
      CSS <length> value.
   */
  contain-intrinsic-size: auto none auto 150px; 
}

如何实现content-visibility: hidden

  1. 识别内容较多的部分:找到最初隐藏的布局块(例如大型数据表中的额外行)。
  2. 应用 CSS:将 content-visibility: hidden 添加到元素中。
  3. 显示元素:当需要显示元素时,将 content-visibility 属性更改为 visible 或 auto。

示例代码

.cached-view {
  /* Hides content but caches rendering state */
  content-visibility: hidden;
}

.cached-view.is-active {
  content-visibility: visible;
}

由于 content-visibility: hidden 会从无障碍树和页内查找搜索中排除元素及其子元素,因此如果内容在隐藏时仍必须可被发现,请不要使用它。如果您需要让隐藏的内容仍可通过原生“在页面中查找”功能进行搜索,请按照搜索隐藏的内容中所述使用 hidden="until-found"。

最佳做法

  • 务必将 contain-intrinsic-size 与 content-visibility: auto 搭配使用。否则,系统会在滚动时强制重新计算高度,从而导致视口布局跳动或出现视觉故障。
  • 请勿对首屏视口内的元素应用 content-visibility: auto,因为这会延迟关键网页渲染。
  • 强制性无障碍验证:应用 content-visibility: auto 时,您必须验证键盘顺序可达性。在某些辅助技术配置中,使用 content-visibility: auto 的屏幕外节点可能会被排除在无障碍树或顺序导航路线之外,直到焦点被强制移入其中。仅使用键盘测试跨屏幕边界的线性导航。

后备策略

content-visibility 后备

如果浏览器不支持 content-visibility,则会忽略该属性。在大多数情况下,content-visibility: auto 不需要后备,但如果没有后备,性能提升将会丧失。不受支持的浏览器会使 content-visibility: hidden 元素完全可见。使用特征检测来实现后备方案。

/* Default for everyone */
.inactive {
  display: none;
}

/* Modern Browsers only */
@supports (content-visibility: hidden) {
 .inactive {
    display: block; /* Turn the layout box back on */
    content-visibility: hidden;
  }
}