使用第三方嵌入代码的最佳做法

概述了高效加载热门第三方嵌入内容的技术。

Addy Osmani
Addy Osmani
Katie Hempenius
Katie Hempenius
Leena Sohoni
Leena Sohoni

许多网站通过将网页的某些部分委托给其他内容提供商,使用第三方嵌入内容来打造富有吸引力的用户体验。第三方内容嵌入最常见的示例包括视频播放器、社交媒体信息流、地图和广告。

第三方内容可能会通过多种方式影响网页的性能。它可能会阻塞呈现、与其他关键资源争用网络和带宽,或者影响核心 Web Vitals 指标。第三方嵌入内容在加载时也可能会导致布局偏移。本文介绍了在加载第三方嵌入内容时可采用的性能最佳实践、高效的加载技术,以及有助于减少热门嵌入内容布局偏移的布局偏移终止器工具。

什么是嵌入

第三方嵌入内容是指在您的网站上显示的任何内容,且符合以下条件:

  • 不是由您创作
  • 从第三方服务器投放

显示多个屏幕外嵌入内容,这些内容可以延迟加载

嵌入内容经常用于以下场景:

  • 与体育、新闻、娱乐和时尚相关的网站会使用视频来补充文字内容。
  • 拥有有效 Twitter 账号或社交媒体账号的组织会将这些账号中的 Feed 嵌入到其网页中,以吸引更多用户并触达更多用户。
  • 餐厅、公园和活动场所页面通常会嵌入地图。

第三方嵌入内容通常会在页面上的 <iframe> 元素中加载。第三方提供商提供的 HTML 代码段通常由 <iframe> 组成,用于提取由标记、脚本和样式表组成的网页。有些提供商还会使用动态注入 <iframe> 的脚本段,以提取其他内容。这可能会导致第三方嵌入内容变得庞大,并延迟其第一方内容,从而影响页面的性能。

第三方嵌入对性能的影响

许多热门嵌入内容包含超过 100 KB 的 JavaScript,有时甚至高达 2 MB。它们的加载时间较长,并且在执行时会使主线程保持繁忙状态。LighthouseChrome 开发者工具等性能监控工具有助于衡量第三方嵌入对性能的影响

降低第三方代码的影响 Lighthouse 审核会显示网页使用的第三方提供商列表,以及大小和主线程阻塞时间。您可以通过 Chrome 开发者工具中的 Lighthouse 标签页执行此审核。

由于嵌入源代码可能会发生变化,因此建议您定期审核嵌入内容和第三方代码对性能的影响。您可以借此机会移除所有冗余代码。

降低第三方代码的影响

加载最佳做法

第三方嵌入可能会对性能产生负面影响,但它们也提供了重要的功能。如需高效使用第三方嵌入内容并降低其对性能的影响,请遵循以下准则。

脚本排序

在设计良好的页面中,主要的第一方内容将成为页面重点,而第三方嵌入内容将占据侧边栏或显示在第一方内容之后。

为了提供最佳用户体验,主要内容应快速加载,并且应先于任何其他辅助内容加载。例如,新闻页面上的新闻文本应在 Twitter Feed 或广告嵌入之前加载。

第三方嵌入请求可能会妨碍第一方内容加载,因此第三方脚本标记的位置非常重要。脚本可能会影响加载顺序,因为在脚本执行期间,DOM 构建会暂停。将第三方脚本代码放在关键的第一方代码后面,并使用 asyncdefer 属性异步加载它们。

<head>
   <title>Order of Things</title>
   <link rel="stylesheet" media="screen" href="/assets/application.css">
   <script src="index.js"></script>
   <script src="https://example.com/3p-library.js" async></script>
</head>

延迟加载

由于第三方内容通常位于主要内容之后,因此在网页加载时,第三方内容可能不会显示在视口中。在这种情况下,系统可能会推迟下载第三方资源,直到用户滚动到相应网页部分。这不仅有助于优化初始网页加载速度,还能降低使用固定流量套餐和网络连接速度缓慢的用户的下载费用。

将内容的加载延迟到实际需要时才加载,称为延迟加载。根据要求和嵌入类型,您可以使用不同的延迟加载技术。

针对 <iframe> 的浏览器延迟加载

对于通过 <iframe> 元素加载的第三方嵌入内容,您可以使用浏览器级延迟加载来推迟加载屏幕外 iframe,直到用户滚动到相应位置。<iframe> 的 loading 属性适用于所有现代浏览器

<iframe src="https://example.com"
       loading="lazy"
       width="600"
       height="400">
</iframe>

loading 属性支持以下值:

  • lazy:表示浏览器应推迟加载 iframe。当 iframe 接近视口时,浏览器会加载该 iframe。如果 iframe 适合延迟加载,请使用此属性。
  • eager:立即加载 iframe。如果 iframe 不适合延迟加载,请使用此方法。如果未指定 loading 属性,则默认行为是此行为,精简模式除外。
  • auto:浏览器确定是否延迟加载此帧。

不支持 loading 属性的浏览器会忽略该属性,因此您可以将浏览器级延迟加载作为渐进式增强功能应用。支持该属性的浏览器可能会对距离视口阈值(iframe 开始加载的距离)采用不同的实现方式。

以下是针对不同类型的嵌入内容延迟加载 iframe 的一些方法。

  • YouTube 视频:如需延迟加载 YouTube 视频播放器 iframe,请在 YouTube 提供的嵌入代码中添加 loading 属性。延迟加载 YouTube 嵌入内容可以在初始页面加载时节省约 500 KB。
<iframe src="https://www.youtube.com/embed/aKydtOXW8mI"
   width="560" height="315"
   loading="lazy"
   title="YouTube video player"
   frameborder="0"
   allow="accelerometer; autoplay; clipboard-write;
            encrypted-media; gyroscope; picture-in-picture"
   allowfullscreen>
</iframe>
  • Google 地图:如需延迟加载 Google 地图 iframe,请在 Google Maps Embed API 生成的 iframe 嵌入代码中添加 loading 属性。以下代码示例包含 Google Cloud API 密钥的占位符。
<iframe src="https://www.google.com/maps/embed/v1/place?key=API_KEY&q=PLACE_ID"
   width="600" height="450"
   style="border:0;"
   allowfullscreen=""
   loading="lazy">
</iframe>

lazysizes 库

由于浏览器除了使用有效的连接类型和 Lite 模式等信号来确定何时应加载 iframe 之外,还会使用嵌入内容与视口的距离来确定何时应加载 iframe,因此浏览器的延迟加载可能会不一致。如果您需要更好地控制距离阈值,或者希望在各种浏览器中提供一致的延迟加载体验,可以使用 lazysizes 库。

lazysizes 是一款快速且符合 SEO 要求的延迟加载器,适用于图片和 iframe。下载该组件后,您可以将其与 YouTube 嵌入的 iframe 搭配使用,如下所示。

<script src="lazysizes.min.js" async></script>

<iframe data-src="https://www.youtube.com/embed/aKydtOXW8mI"
   width="560" height="315"
   class="lazyload"
   title="YouTube video player"
   frameborder="0"
   allow="accelerometer; autoplay; clipboard-write;
        encrypted-media; gyroscope; picture-in-picture"
   allowfullscreen>
</iframe>

同样,lazysizes 也可与 iframe 搭配使用,以嵌入其他第三方内容。

请注意,lazysizes 使用 Intersection Observer API 来检测元素何时变为可见。

在 Facebook 中使用 data-lazy

Facebook 提供了可嵌入的不同类型的社交插件。这包括帖子、评论、视频和最受欢迎的按钮。所有插件都包含 data-lazy 设置。将其设置为 true 可确保插件通过设置 loading="lazy" iframe 属性来使用浏览器的延迟加载机制。

延迟加载 Instagram 动态

Instagram 会在嵌入内容中提供一段标记和一个脚本。该脚本会将 <iframe> 注入到网页中。延迟加载此 <iframe> 可以提高性能,因为经过 GZIP 压缩后的嵌入内容的大小可能会超过 100 KB。许多适用于 WordPress 网站的 Instagram 插件(例如 WPZoomElfsight)都提供延迟加载选项。

将嵌入替换为外观

虽然互动式嵌入内容会为网页增添价值,但许多用户可能不会与其互动。例如,并非浏览餐厅页面的每位用户都会点击、展开、滚动和浏览嵌入的地图。同样,并非访问电信服务提供商页面的每位用户都会与聊天机器人互动。在这些情况下,您可以通过显示外观来避免加载或延迟加载嵌入内容。

带有放大和缩小功能的地图嵌入。
地图嵌入
地图外观(即图片)。
地图外观

外观是一种静态元素,看起来与实际嵌入的第三方元素类似,但没有任何功能,因此对页面加载的开销要小得多。以下是一些策略,可帮助您以最佳方式加载此类嵌入内容,同时仍能为用户提供一些价值。

将静态图片用作外观

在您可能不需要使地图具有互动性的情况下,可以使用静态图片来替代地图嵌入。您可以放大地图上的感兴趣区域,截取图片,然后使用该图片代替互动式地图嵌入。您还可以使用 DevTools 的当前节点屏幕截图功能截取嵌入的 iframe 元素的屏幕截图。

截取节点屏幕截图

DevTools 会将图片捕获为 png,但您也可以考虑将其转换为 WebP 格式以提升性能

将动态图片用作外墙

借助此方法,您可以在运行时生成与交互式嵌入内容对应的图片。下面列出了一些可用于在网页上生成嵌入内容静态版本的工具。

  • Maps Static API:Google Maps Static API 服务会根据标准 HTTP 请求中包含的网址参数生成地图,并将地图作为图片返回,以便您在网页上显示。网址需要包含 Google Maps API 密钥,并且必须作为 src 属性放置在网页上的 <img> 标记中。

    静态地图制作工具可帮助您配置网址所需的参数,并实时为您提供图片元素的代码。

    以下代码段显示了将来源设置为 Google 地图静态 API 网址的图片的代码。该链接已包含在链接标记中,以确保用户可以通过点击图片访问实际地图。(注意:网址不包含 API 密钥属性)

    <a href="https://www.google.com/maps/place/Albany,+NY/">
    <img src="https://maps.googleapis.com/maps/api/staticmap?center=Albany,+NY&zoom=13&scale=1&size=600x300&maptype=roadmap&format=png&visual_refresh=true" alt="Google Map of Albany, NY">
    </a>
    
  • Twitter 屏幕截图:与地图屏幕截图类似,借助此概念,您可以动态嵌入 Twitter 屏幕截图,而不是实时动态。Tweetpik 是可用于截取推文屏幕截图的工具之一。Tweetpik API 接受推文的网址,并返回包含其内容的图片。该 API 还接受参数,以自定义图片的背景、颜色、边框和尺寸。

使用点击即可加载功能来增强外观

点击即可加载的概念将延迟加载和外观结合在一起。页面最初会随外观一起加载。当用户通过点击与静态占位符互动时,系统会加载第三方嵌入内容。这也称为“在互动时导入”模式,可通过以下步骤实现。

  1. 页面加载时:页面上包含外观或静态元素。
  2. 当鼠标悬停时:Facade 会预先连接到第三方嵌入提供商。
  3. 点击:外观会被第三方产品取代。

外观可与第三方嵌入的视频播放器、聊天 widget、身份验证服务和社交媒体 widget 搭配使用。我们经常会遇到仅包含播放按钮的图片形式的 YouTube 视频嵌入。只有在您点击图片后,系统才会加载实际视频。

您可以使用点击时导入模式构建自定义点击即可加载的外观,也可以使用以下适用于不同类型嵌入的开源外观之一。

  • YouTube 外墙

    Lite-youtube-embed 是 YouTube 播放器的推荐外观,看起来像真实的播放器,但速度快了 224 倍。您可以通过下载脚本和样式表,然后在 HTML 或 JavaScript 中使用 <lite-youtube> 标记来使用该库。您可以通过 params 属性添加 YouTube 支持的自定义播放器参数。

    <lite-youtube videoid="ogfYd705cRs" playlabel="Play: Keynote (Google I/O '18)"></lite-youtube>
    

    以下是 lite-youtube-embed 与实际嵌入代码之间的对比。

    精简版 YouTube 嵌入
    精简版 YouTube 嵌入代码
    实际的 YouTube 嵌入
    YouTube 嵌入代码

    适用于 YouTube 和 Vimeo 播放器的其他类似外观是 lite-youtubelite-vimeo-embedlite-vimeo

  • Chat 微件外观

    React 实时聊天加载器会加载一个看起来像聊天嵌入的按钮,而不是嵌入本身。它可与各种聊天服务提供商平台(例如 Intercom、Help Scout、Messenger)搭配使用。类似聊天 widget 比聊天 widget 轻量得多,加载速度也更快。当用户悬停或点击该按钮,或者网页长时间处于空闲状态时,此按钮会替换为实际的聊天 widget。Postmark 案例研究介绍了他们如何实现 react-live-chat-loader 以及取得的性能改进。

    Postmark 聊天 widget

如果您发现某些第三方嵌入会导致加载性能不佳,并且无法使用之前介绍的任何方法,最简单的方法就是完全移除嵌入内容。如果您仍希望用户能够访问嵌入内容,可以使用 target="_blank" 提供指向该内容的链接,以便用户点击该链接并在其他标签页中查看该内容。

布局稳定性

虽然动态加载嵌入内容可以提高页面的加载性能,但有时可能会导致页面内容意外移动。这称为布局偏移。

由于视觉稳定性对流畅的用户体验至关重要,因此 Cumulative Layout Shift (CLS) 用于衡量这些偏移的发生频率和干扰程度。

在网页加载期间为稍后要动态加载的元素预留空间,可以避免布局偏移。如果浏览器知道元素的宽度和高度,则可以确定要预留的空间。您可以通过指定 iframe 的 widthheight 属性,或为将要加载第三方嵌入内容的静态元素设置固定大小,来确保这一点。例如,YouTube 嵌入的 iframe 应按如下方式指定宽度和高度。

<iframe src="https://www.youtube.com/embed/aKydtOXW8mI" width="560" height="315">
</iframe>

YouTube、Google 地图和 Facebook 等热门嵌入内容会提供带有尺寸属性的嵌入代码。不过,有些提供商可能不会提供此信息。例如,以下代码段未指明生成的嵌入的尺寸。

<a class="twitter-timeline" href="https://twitter.com/ChannelNewsAsia?ref_src=twsrc%5Etfw" data-tweet-limit="1">Tweets by ChannelNewsAsia</a>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

在该页面呈现后,您可以使用 DevTools 检查注入的 iframe。如以下代码段所示,注入的 iframe 的高度是固定的,而宽度以百分比指定。

<iframe id="twitter-widget-0" scrolling="no" frameborder="0" allowtransparency="true" allowfullscreen="true" class="twitter-timeline twitter-timeline-rendered" style="position: static; visibility: visible; display: inline-block; width: 100%; padding: 0px; border: none; max-width: 1000px; min-width: 180px; margin-top: 0px; margin-bottom: 0px; min-height: 200px; height: 6238.31px;" data-widget-id="profile:ChannelNewsAsia" title="Twitter Timeline">
</iframe>

此信息可用于设置容器元素的大小,以确保容器在加载 Feed 时不会展开,并且不会发生布局偏移。您可以使用以下代码段来固定之前添加的嵌入内容的大小。

<style>
    .twitterfeed { display: table-cell;  vertical-align: top; width: 100vw; }
    .twitter-timeline {height: 400px !important; }
</style>
<div class=twitterfeed>
       <a class="twitter-timeline" href="https://twitter.com/ChannelNewsAsia?ref_src=twsrc%5Etfw" data-tweet-limit="1">Tweets by ChannelNewsAsia</a>
       <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>

布局偏移终止符

由于第三方嵌入内容通常会省略其呈现的最终内容的尺寸(宽度、高度),因此可能会导致网页上出现明显的布局偏移。如果不使用 DevTools 在各种不同视口大小下手动检查最终尺寸,则很难解决此问题。

现在,我们推出了一款自动化工具 Layout Shift Terminator,可帮助您减少来自热门嵌入内容(例如 Twitter、Facebook 和其他提供商)的布局偏移。

布局偏移终止符:

  • 在 iFrame 中加载嵌入的客户端。
  • 将 iframe 调整为各种常见的视口尺寸。
  • 针对每个常用视口,捕获嵌入的尺寸,以便稍后生成媒体查询和容器查询。
  • 使用媒体查询(和容器查询)调整嵌入代码周围的最小高度封装容器的大小,直到嵌入代码初始化(此后,系统会移除最小高度样式)。
  • 生成经过优化的嵌入代码段,您可以将其复制并粘贴到您原本要在网页中添加嵌入代码的位置。

    布局偏移终端

欢迎试用布局偏移终止器,并随时在 GitHub 上留下任何反馈。该工具目前处于 Beta 版阶段,我们会不断改进,使其日后更加完善。

总结

第三方嵌入内容可以为用户提供诸多价值,但随着网页上嵌入内容的数量和大小增加,性能可能会受到影响。因此,您需要根据嵌入内容的位置、相关性和潜在用户的需求,对其进行衡量、评判并采用适当的加载策略。