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

有效加载热门第三方嵌入的技术的概述。

艾迪·奥斯曼尼
Addy Osmani
凯蒂·亨佩纽斯
Katie Hempenius
莉娜·索霍尼
Leena Sohoni

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

第三方内容可能会在很多方面影响网页的性能。它可能会阻塞渲染、与其他关键网络和带宽资源争用,或者影响 Core Web Vitals 指标。第三方嵌入也可能会导致加载时布局发生变化。本文介绍了加载第三方嵌入时可采用的性能最佳实践、高效加载技巧,以及有助于减少常见嵌入的布局偏移的“布局偏移终结器”工具。

什么是嵌入

第三方嵌入内容是指在您的网站上显示的任何内容: * 并非由您创作 * 由第三方服务器提供

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

嵌入式功能经常用于以下领域: * 与体育、新闻、娱乐和时尚相关的网站会使用视频来增强文字内容。 * 拥有活跃 Twitter 或社交媒体帐号的组织可将这些帐号中的信息流嵌入其网页中,以便吸引和覆盖更多用户。 * 餐馆、公园和活动场地页面通常会嵌入地图。

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

第三方嵌入对性能的影响

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

减少第三方代码的影响 Lighthouse 审核会显示页面使用的第三方提供程序的列表,以及大小和主线程阻塞时间。此项审计可通过 Chrome 开发者工具的“Lighthouse”标签页下查看。

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

降低第三方代码的影响

加载最佳做法

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

脚本排序

在设计良好的网页中,关键的第一方内容将是网页的重点,而第三方嵌入的内容则占据侧边栏或显示在第一方内容之后。

为了提供最佳用户体验,主要内容应快速加载,且在任何其他支持内容之前加载。例如,新闻网页上的新闻文字应在嵌入 Twitter 信息流或广告之前加载。

请求第三方嵌入会妨碍第一方内容的加载,因此第三方脚本标记的位置非常重要。脚本可能会影响加载顺序,因为 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> 的加载属性可在 Chrome 77 及更高版本中使用,并且也已引入其他基于 Chromium 的浏览器。

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

加载属性支持以下值:

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

不支持 loading 属性的浏览器会忽略该属性,因此,您可以将原生延迟加载作为渐进式增强功能。支持该属性的浏览器可能会针对 distance-from-viewport 阈值(即 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 库

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

lazysizes 是适用于图片和 iframe 的快速且便于搜索引擎优化 (SEO) 的延迟加载器。下载该组件后,您就可以将其与适用于 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 中使用数据延迟

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

延迟加载 Instagram 信息流

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

将嵌入替换为 Facade

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

包含缩放功能的地图嵌入。
地图嵌入
即图像形式的地图立面。
地图立面

Facade 是一种静态元素,与实际嵌入的第三方网站很相似,但并不能发挥作用,因此对网页加载造成的负担要少得多。下文介绍了几种策略,旨在以最佳方式加载此类嵌入,同时仍然为用户提供一些价值。

将静态图片用作 Facade

您可以使用静态图片代替地图嵌入,因为在这类情况下,您不需要使地图具有互动性。您可以放大地图上感兴趣的区域,拍摄图片,然后使用此图片而不是交互式地图嵌入。您还可以使用开发者工具的捕获节点屏幕截图功能截取嵌入式 iframe 元素的屏幕截图,如下所示。

截取节点屏幕截图

开发者工具会将图片作为 png 进行捕获,但您也可以考虑将其转换为 WebP format for better performance

将动态图片用作 Facade

通过此方法,您可以在运行时生成与交互式嵌入相对应的图像。下面介绍的一些工具可让您在网页上生成嵌入内容的静态版本。

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

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

    以下代码段展示了源代码设置为 Maps Static API 网址的图片的代码。它包含在 link 标记中,以确保可以通过点击图像访问实际地图。(注意:网址中不包含 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 屏幕截图,而不是实时 Feed。Tweetpik 是一款可用于截取 Twitter 微博屏幕截图的工具。Tweetpik API 接受推文的网址,并返回图片及其内容。该 API 还接受用于自定义图片的背景、颜色、边框和尺寸的参数。

使用点击加载来增强立面

“点击加载”概念将延迟加载和 Facade 相结合。该网页最初通过 Facade 加载。当用户点击静态占位符与其互动时,系统会加载第三方嵌入代码。这也称为“互动时导入”模式,可按照以下步骤实现。

  1. 网页加载时:网页包含 Facade 或静态元素。
  2. 鼠标悬停时:Facade 会预连接到第三方嵌入提供程序。
  3. 点击时:正面被第三方产品替换。

Facade 可与适用于视频播放器、聊天微件、身份验证服务和社交媒体微件的第三方嵌入一起使用。我们经常会遇到的 YouTube 视频嵌入式视频只包含带有播放按钮的图片。只有在您点击图片时,实际视频才会加载。

您可以使用互动时导入模式构建自定义点击加载 Facade,也可以使用以下可用于不同类型的嵌入的开源 Facade。

  • YouTube 首页

    Lite-youtube-embed 是 YouTube 播放器的推荐 Facade,它虽然看起来像是真实播放器,但速度要快 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 播放器的类似 Facade 包括 lite-youtubelite-vimeo-embedlite-vimeo

  • 聊天微件 Facade

    React-live-chat-loader 会加载一个看起来像聊天嵌入内容(而非嵌入内容本身)的按钮。它可与各种聊天服务提供商平台搭配使用,例如 Intercom、Help Scout、Messenger 等。相似微件比聊天微件要小得多,而且加载速度也更快。当用户将光标悬停在按钮上或点击按钮时,或页面长时间闲置时,此按钮可替换为实际的聊天微件。Postmark 案例研究介绍了他们如何实现 Reaction-live-chat-loader 并实现性能提升。

    邮戳聊天微件

如果您发现某些第三方嵌入会导致加载性能不佳,因此不能选择使用上述任何技术,最简单的方法是完全删除嵌入。如果您仍希望用户能够访问嵌入内容中的内容,可以使用 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>

呈现此页面后,您可以使用开发者工具检查注入的 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>

布局偏移终止符

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

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

布局偏移终止符:

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

    Layour 轮班终端

欢迎试用 Layout Shift Terminator,并欢迎您在 GitHub 上提供任何反馈。该工具目前处于 Beta 版阶段,旨在通过进一步优化不断改进。

总结

第三方嵌入可以为用户提供很多价值,但是,随着网页上的嵌入数量和大小的增加,性能也会受到影响。因此,我们需要根据嵌入的位置、相关性和潜在用户的需求来衡量、判断和使用适合的加载策略。