高效加载常用第三方嵌入的技术概述。
许多网站使用第三方嵌入,通过将网页的某些部分委托给其他内容提供商来创建引人入胜的用户体验。第三方内容嵌入最常见的示例是视频播放器、社交媒体 feed、地图和广告。
第三方内容会以多种方式影响页面的性能。它可能会阻止渲染,与其他关键资源争夺网络和带宽,或影响 Core Web Vitals 指标。第三方嵌入也可能在加载时导致布局偏移。本文讨论了在加载第三方嵌入时可以使用的性能最佳实践、高效的加载技术以及 Layout Shift Terminator 工具,该工具可帮助减少常用嵌入的布局偏移。
什么是嵌入
第三方嵌入是指您网站上显示的任何内容,这些内容
- 不是由您创作的
- 从第三方服务器提供
嵌入经常用于以下方面
- 与体育、新闻、娱乐和时尚相关的网站使用视频来增强文本内容。
- 拥有活跃 Twitter 或社交媒体帐户的组织在其网页上嵌入来自这些帐户的 feed,以吸引和联系更多人。
- 餐厅、公园和活动场所页面通常嵌入地图。
第三方嵌入通常在页面上的 <iframe>
元素中加载。第三方提供商提供 HTML 代码段,通常由一个 <iframe>
组成,该代码段会拉取一个由标记、脚本和样式表组成的页面。一些提供商还使用脚本代码段来动态注入 <iframe>
以拉取其他内容。这可能会使第三方嵌入变得繁重,并通过延迟其第一方内容来影响页面的性能。
第三方嵌入的性能影响
许多流行的嵌入包含超过 100 KB 的 JavaScript,有时甚至高达 2 MB。它们需要更多时间来加载,并在执行时使主线程保持繁忙。性能监控工具(如 Lighthouse 和 Chrome DevTools)有助于 衡量第三方嵌入对性能的影响。
减少第三方代码的影响 Lighthouse 审核显示了页面使用的第三方提供商列表,以及大小和主线程阻塞时间。审核可通过 Chrome DevTools 在 Lighthouse 选项卡下获得。
定期审核嵌入和第三方代码的性能影响是一个好习惯,因为嵌入源代码可能会更改。您可以利用此机会删除任何冗余代码。
加载最佳实践
第三方嵌入可能会对性能产生负面影响,但它们也提供了重要的功能。为了高效地使用第三方嵌入并减少其性能影响,请遵循以下准则。
脚本排序
在一个设计良好的页面中,关键的第一方内容将是页面的焦点,而第三方嵌入将占据侧边栏或在第一方内容之后出现。
为了获得最佳用户体验,主要内容应快速加载并在任何其他辅助内容之前加载。例如,新闻页面上的新闻文本应在 Twitter feed 或广告的嵌入之前加载。
第三方嵌入的请求可能会妨碍第一方内容的加载,因此第三方脚本标记的位置很重要。脚本会影响加载顺序,因为在执行脚本时 DOM 构建会暂停。将第三方脚本标记放在关键的第一方标记之后,并使用 async
或 defer
属性以异步方式加载它们。
<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 是延迟加载的良好候选者,则使用此值。eager
:立即加载 iframe。如果 iframe 不是延迟加载的良好候选者,则使用此值。如果未指定loading
属性,则这是默认行为,但在 精简模式 下除外。auto
:浏览器确定是否延迟加载此帧。
不支持 loading
属性的浏览器会忽略它,因此您可以将浏览器级延迟加载应用为渐进增强。支持该属性的浏览器可能对 距视口距离 阈值(iframe 开始加载的距离)有不同的实现。
以下是一些可以延迟加载不同类型嵌入的 iframe 的方法。
- YouTube 视频:要延迟加载 YouTube 视频播放器 iframe,请将
loading
属性添加到 YouTube 提供的嵌入代码中。延迟加载 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,请将
loading
属性包含在 Google Maps Embed API 生成的 iframe 嵌入代码中。以下是代码示例,其中包含 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 是一个快速、对 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 feed
Instagram 提供了一个标记块和一个脚本作为嵌入的一部分。该脚本将 <iframe>
注入到页面中。延迟加载此 <iframe>
可以提高性能,因为嵌入的大小可能超过 100 KB(gzip 压缩后)。许多适用于 WordPress 站点的 Instagram 插件(如 WPZoom 和 Elfsight)都提供了延迟加载选项。
用外观模式替换嵌入
虽然交互式嵌入为页面增加了价值,但许多用户可能不会与之交互。例如,并非每个浏览餐厅页面的用户都会单击、展开、滚动和导航地图嵌入。同样,并非每个电信服务提供商页面的用户都会与聊天机器人交互。在这些情况下,您可以通过显示外观模式来完全避免加载或延迟加载嵌入。


外观模式是一个静态元素,看起来类似于实际嵌入的第三方,但没有功能,因此对页面加载的负担要小得多。以下是一些以最佳方式加载此类嵌入的策略,同时仍为用户提供一些价值。
使用静态图像作为外观模式
在您可能不需要使地图具有交互性的情况下,可以使用静态图像代替地图嵌入。您可以放大地图上感兴趣的区域,捕获图像,并使用它代替交互式地图嵌入。您还可以使用 DevTools 捕获节点屏幕截图功能来捕获嵌入的 iframe
元素的屏幕截图。
DevTools 将图像捕获为 png
,但您也可以考虑将其转换为 WebP 格式以获得更好的性能。
使用动态图像作为外观模式
此技术使您可以在运行时生成与交互式嵌入对应的图像。以下是一些允许您在页面上生成嵌入的静态版本的工具。
Maps Static API:Google Maps Static API 服务根据标准 HTTP 请求中包含的 URL 参数生成地图,并将地图作为图像返回,您可以在网页上显示该图像。 URL 需要包含 Google Maps API 密钥,并且必须作为
src
属性放置在页面上的<img>
标记中。静态地图制作工具 帮助配置 URL 所需的参数,并实时为您提供图像元素的代码。
以下代码段显示了源设置为 Maps Static API URL 的图像代码。它已包含在链接标记中,以确保可以通过单击图像访问实际地图。(注意:URL 中未包含 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 是可用于拍摄推文屏幕截图的工具之一。 Tweetpik API 接受推文的 URL 并返回包含其内容的图像。 API 还接受用于自定义图像的背景、颜色、边框和尺寸的参数。
使用点击加载来增强外观模式
点击加载概念结合了延迟加载和外观模式。页面最初加载时带有外观模式。当用户通过单击静态占位符与之交互时,将加载第三方嵌入。这也称为交互时导入模式,可以使用以下步骤实现。
- 在页面加载时:页面上包含外观模式或静态元素。
- 在鼠标悬停时:外观模式预连接到第三方嵌入提供商。
- 在点击时:外观模式被第三方产品替换。
外观模式可以与视频播放器、聊天小部件、身份验证服务和社交媒体小部件的第三方嵌入一起使用。我们经常遇到的带有播放按钮的 YouTube 视频嵌入(只是图像)就是外观模式。实际视频仅在您单击图像时加载。
您可以使用交互时导入模式构建自定义点击加载外观模式,或使用以下适用于不同类型嵌入的开源外观模式之一。
YouTube 外观模式
Lite-youtube-embed 是 YouTube 播放器的推荐外观模式,它看起来像真实的播放器,但速度快 224 倍。可以通过下载脚本和样式表,然后在 HTML 或 JavaScript 中使用
<lite-youtube>
标记来使用它。 YouTube 支持的自定义播放器参数可以通过params
属性包含。<lite-youtube videoid="ogfYd705cRs" playlabel="Play: Keynote (Google I/O '18)"></lite-youtube>
以下是 lite-youtube-embed 和实际嵌入之间的比较。
lite-YouTube 嵌入 YouTube 嵌入 其他可用于 YouTube 和 Vimeo 播放器的类似外观模式包括 lite-youtube、lite-vimeo-embed 和 lite-vimeo。
聊天小部件外观模式
React live chat loader 加载一个看起来像聊天嵌入的按钮,而不是嵌入本身。它可以与各种聊天提供商平台(如 Intercom、Help Scout、Messenger)一起使用。外观相似的小部件比聊天小部件轻得多,加载速度更快。当用户悬停或单击按钮,或者页面空闲时间过长时,它可以被实际的聊天小部件替换。 Postmark 案例研究 解释了他们如何实现
react-live-chat-loader
以及他们实现的性能改进。
删除嵌入或将其替换为链接
如果您发现某些第三方嵌入导致加载性能不佳,并且使用之前描述的任何技术都不是一种选择,那么您可以做的最简单的事情就是完全删除嵌入。如果您仍然希望用户能够访问嵌入中的内容,您可以提供一个指向它的链接,并使用 target="_blank"
,以便用户可以单击并在另一个选项卡中查看它。
布局稳定性
虽然动态加载嵌入内容可以提高页面的加载性能,但有时会导致页面内容意外移动。这称为布局偏移。
由于视觉稳定性对于流畅的用户体验非常重要,因此累积布局偏移 (CLS) 衡量这些偏移发生的频率以及它们的破坏性程度。
可以通过在页面加载期间为稍后将动态加载的元素保留空间来避免布局偏移。如果浏览器知道元素的宽度和高度,则可以确定要保留的空间。您可以通过指定 iframe 的 width
和 height
属性,或者为将加载第三方嵌入的静态元素设置固定大小来确保这一点。例如,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>
Layout Shift Terminator
由于第三方嵌入通常省略它们呈现的最终内容的尺寸(宽度、高度),因此它们可能会导致页面上发生明显的布局偏移。如果不使用 DevTools 在各种不同视口大小下手动检查最终尺寸,则此问题可能很难解决。
现在有一个自动化工具 Layout Shift Terminator,它可以帮助您减少来自常用嵌入(例如来自 Twitter、Facebook 和其他提供商)的布局偏移。
Layout Shift Terminator
- 在客户端 iframe 中加载嵌入。
- 将 iframe 调整为各种流行的视口大小。
- 对于每个流行的视口,捕获嵌入的尺寸,以便稍后生成媒体查询和容器查询。
- 使用媒体查询(和容器查询)在嵌入标记周围调整最小高度包装器的大小,直到嵌入初始化(之后最小高度样式将被删除)。
生成优化的嵌入代码段,您可以将其复制并粘贴到您原本要将嵌入包含在页面的位置。
试用 Layout Shift Terminator,并随时在 GitHub 上留下任何反馈。该工具目前处于 Beta 状态,旨在通过进一步的改进随着时间的推移而改进。
结论
第三方嵌入可以为用户提供很多价值,但随着页面上嵌入的数量和大小的增加,性能可能会受到影响。这就是为什么有必要根据嵌入的位置、相关性和潜在用户的需求来衡量、判断和使用适当的嵌入加载策略。