浏览器级 CMS 延迟加载

采用标准化 loading 属性的学习经验

我写这篇文章的目的是说服 CMS 平台开发者和贡献者(即开发 CMS 核心的人员)现在是时候实现对浏览器级图片延迟加载功能的支持了。我还将分享关于如何确保高质量用户体验以及如何在实现延迟加载的同时支持其他开发者进行自定义的建议。这些指南来自于我们在为 WordPress 添加支持以及帮助 Joomla、Drupal 和 TYPO3 实现该功能的经验。

无论您是 CMS 平台开发者还是 CMS 用户(即使用 CMS 构建网站的人员),您都可以使用这篇文章来详细了解在 CMS 中使用浏览器级延迟加载的好处。查看后续步骤部分,了解关于如何鼓励您的 CMS 平台实现延迟加载的建议。

背景

在过去一年中,使用 loading 属性延迟加载图片和 iframe 已经成为 WHATWG HTML 标准的一部分,并且已被各种浏览器日益广泛地采用。然而,这些里程碑只是为更快、更节省资源的 web 奠定了基础。现在,分布式 web 生态系统需要充分利用 loading 属性。

内容管理系统为大约 60% 的网站提供支持,因此这些平台在将现代浏览器功能普及到 web 方面发挥着至关重要的作用。随着一些流行的开源 CMS(例如 WordPressJoomlaTYPO3)已经实现了对图片 loading 属性的支持,让我们来看看他们的方法以及对在其他 CMS 平台中采用该功能也相关的要点。延迟加载媒体是一项关键的 web 性能功能,网站应该大规模地从中受益,因此建议在 CMS 核心级别采用它。

现在实现延迟加载的理由

标准化

在 CMS 中采用非标准化的浏览器功能有助于广泛的测试,并可以发现潜在的改进领域。但是,CMS 的普遍共识是,只要浏览器功能尚未标准化,就最好以相应平台的扩展程序或插件的形式实现。只有在标准化之后,才能考虑在平台核心中采用某项功能。

浏览器支持

浏览器对该功能的支持是一个类似的问题:大多数 CMS 用户应该能够从该功能中受益。如果相当一部分浏览器尚不支持该功能,则该功能必须确保至少对这些浏览器没有不利影响。

距视口距离阈值

延迟加载实现的一个常见问题是,原则上,它们会增加图片在用户的视口中变为可见后仍未加载的可能性,因为加载周期在较晚阶段开始。与以前基于 JavaScript 的解决方案相反,浏览器以保守的方式处理此问题,并且可以根据真实的用户体验数据微调其方法,从而最大限度地减少影响,因此 CMS 平台可以安全地采用浏览器级延迟加载。

用户体验建议

在元素上要求维度属性

为了避免布局偏移,长期以来一直建议图片或 iframe 等嵌入内容应始终包含维度属性 widthheight,以便浏览器可以在实际加载这些元素之前推断出这些元素的纵横比。无论元素是否被延迟加载,此建议都适用。但是,由于图片在视口中时未完全加载的可能性高 0.1%,因此在启用延迟加载后,此建议变得稍微更适用。

CMS 最好在所有图片和 iframe 上提供维度属性。如果并非每个此类元素都能做到这一点,则建议跳过未提供这两个属性的图片的延迟加载。

避免延迟加载首屏元素

目前,建议 CMS 仅将 loading="lazy" 属性添加到位于首屏下方的图片和 iframe,以避免延迟最大内容渲染时间指标,在某些情况下,延迟可能会很明显,正如 2021 年 7 月发现的那样。但是,必须承认的是,在渲染过程之前评估元素相对于视口的位置是复杂的。当 CMS 使用自动化方法添加 loading 属性时,尤其如此,但即使基于人工干预,也必须考虑不同的视口尺寸和纵横比等多种因素。尽管如此,强烈建议不要延迟加载可能会出现在首屏中的焦点图和其他图片或 iframe。

避免 JavaScript 回退

虽然可以使用 JavaScript 为尚不支持 loading 属性的浏览器提供延迟加载,但此类机制始终依赖于最初删除图片或 iframe 的 src 属性,这会导致确实支持该属性的浏览器出现延迟。此外,在大型 CMS 的前端中推出此类基于 JavaScript 的解决方案会增加潜在问题的范围,这也是在标准化的浏览器功能出现之前,没有主要 CMS 在其核心中采用延迟加载的部分原因。

技术建议

默认启用延迟加载

对于实现浏览器级延迟加载的 CMS,总体建议是默认启用它,即应将 loading="lazy" 添加到图片和 iframe,最好仅适用于包含维度属性的元素。默认启用该功能将比必须手动启用该功能(例如,在每张图片的基础上)节省更多的网络资源。

尽可能地,loading="lazy"仅添加到可能出现在首屏下方的元素。虽然由于缺乏客户端感知和各种视口尺寸,CMS 很难实现此要求,但建议至少使用近似的启发式方法来忽略焦点图等可能出现在首屏中的元素,使其不被延迟加载

允许按元素修改

虽然 loading="lazy" 应该默认添加到图片和 iframe,但允许在某些图片上省略该属性至关重要,例如为了优化 LCP。如果 CMS 的受众平均而言被认为更精通技术,则可以为每张图片和 iframe 公开一个 UI 控件,允许选择不延迟加载该元素。或者,可以向第三方开发者公开 API,以便他们可以通过代码进行类似的更改。

例如,WordPress 允许跳过 整个 HTML 标记或上下文内容中的特定 HTML 元素loading 属性。

改造现有内容

从高层次来看,在 CMS 中向 HTML 元素添加 loading 属性有两种方法:

  • 要么从后端的内容编辑器中添加属性,并将其持久保存在数据库中。
  • 要么在前端从数据库渲染内容时动态添加属性。

建议 CMS 选择在渲染时动态添加属性,以便将延迟加载的好处也带给任何现有内容。如果只能通过编辑器添加属性,则只有新的或最近修改的内容才能获得好处,这将大大降低 CMS 在节省网络资源方面的作用。此外,动态添加属性将很容易实现未来的修改,如果浏览器级延迟加载的功能得到进一步扩展。

动态添加属性应该考虑到元素上可能已存在的 loading 属性,并让此类属性优先。这样,CMS 或其扩展程序也可以实现编辑器驱动的方法,而不会导致与重复属性发生冲突。

优化服务器端性能

当使用(例如)服务器端中间件动态地向内容添加 loading 属性时,速度是一个考虑因素。根据 CMS 的不同,可以通过 DOM 遍历或正则表达式添加属性,建议使用后者以获得更好的性能。

正则表达式的使用应保持在最低限度,例如,单个正则表达式,它收集内容中所有 imgiframe 标记(包括它们的属性),然后根据需要将 loading 属性添加到每个标记字符串。例如,WordPress 甚至使用单个通用正则表达式对某些元素执行各种动态操作,其中添加 loading="lazy" 只是其中之一,使用单个正则表达式来支持多种功能。这种形式的优化也是建议在 CMS 核心中而不是在扩展程序中采用延迟加载的另一个原因 - 它允许更好的服务器端性能优化。

后续步骤

查看是否已有功能请求工单来在您的 CMS 中添加对该功能的支持,或者如果没有,则打开一个新的工单。根据需要引用这篇文章以支持您的提案。

在 Twitter 上给我发推文 (@felixarntz@) 提出问题或意见,或者如果已添加对浏览器级延迟加载的支持,请将您的 CMS 列在此页面上。如果您遇到其他挑战,我也很想了解更多信息,希望能找到解决方案。

如果您是 CMS 平台开发者,请研究其他 CMS 如何实现延迟加载

您可以使用您研究的学习经验和这篇文章中的技术建议,开始为您的 CMS 贡献代码,例如以补丁或拉取请求的形式。

焦点图由 Colin WattsUnsplash 上拍摄。