如果您已优化代码,但您的网站加载速度仍然过慢,则可能是第三方脚本造成的。
第三方脚本提供了各种有用的功能,使 Web 更具动态性、互动性和互联性。其中一些甚至可能对您网站的功能或收入来源至关重要。但是使用它们是有风险的
- 它们会降低您网站的性能。
- 它们可能会导致隐私或安全问题。
- 它们可能是不可预测的,并且它们的行为可能会产生意想不到的后果。
理想情况下,您需要确保第三方脚本不会影响您网站的关键渲染路径。在本指南中,我们将逐步介绍如何查找和修复与加载第三方 JavaScript 相关的问题,并最大限度地降低用户面临的风险。
什么是第三方脚本?
第三方 JavaScript 通常指可以直接从第三方供应商嵌入到任何网站中的脚本。例如:
社交分享按钮(Facebook、X、LinkedIn、Mastodon)
视频播放器嵌入(YouTube、Vimeo)
广告 iframe
分析和指标脚本
用于实验的 A/B 测试脚本
帮助程序库,例如日期格式化、动画或函数库

<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/mo8thg5XGV0"
frameborder="0"
allow="autoplay; encrypted-media"
allowfullscreen
>
</iframe>
遗憾的是,嵌入第三方脚本意味着我们通常依赖它们快速运行且不会降低页面速度。第三方脚本是由网站所有者无法控制的资源引起的性能下降的常见原因,包括以下问题:
向多个服务器发送过多的网络请求。网站必须发出的请求越多,加载所需的时间就越长。
发送过多的 JavaScript,使主线程保持繁忙状态。过多的 JavaScript 可能会阻止 DOM 构建,从而延迟页面渲染。CPU 密集型脚本解析和执行可能会延迟用户交互并导致电池电量耗尽。
发送大型的未优化的图像文件或视频可能会消耗数据并花费用户的资金。
安全问题,如果您的页面在没有防范措施的情况下加载脚本,则可能会充当单点故障 (SPOF)。
不充分的HTTP 缓存,迫使浏览器发送更多网络请求来获取资源。
缺乏足够的服务器压缩导致资源加载缓慢。
阻止内容显示,直到它们完成处理。对于异步 A/B 测试脚本来说,情况也是如此。
使用已知会损害用户体验的旧版 API,例如 document.write()。
过多的 DOM 元素或开销大的 CSS 选择器。
包含多个第三方嵌入可能会导致多次拉取多个框架和库,浪费资源并使现有的性能问题变得更糟。
第三方脚本通常使用嵌入技术,如果它们的服务器响应缓慢,即使嵌入使用 async 或 defer,也可能会阻止 window.onload。
您修复第三方脚本问题的能力可能取决于您的网站以及您配置加载第三方代码方式的能力。幸运的是,存在许多解决方案和工具来查找和修复第三方资源的问题。
如何识别页面上的第三方脚本?
识别您网站上的第三方脚本并确定其性能影响是优化它们的第一步。我们建议使用免费的 Web 速度测试工具,包括 Chrome DevTools、PageSpeed Insights 和 WebPageTest,以识别开销大的脚本。这些工具显示丰富的诊断信息,可以告诉您您的网站使用了多少第三方脚本,以及哪些脚本执行时间最长。
WebPageTest 的瀑布图视图可以突出显示大量使用第三方脚本的影响。以下来自 Tags Gone Wild 的图像显示了一个示例图,其中显示了加载网站主要内容所需的网络请求,而不是跟踪和营销脚本。

WebPageTest 的 域分解也可用于可视化来自第三方来源的内容量。它按总字节数和请求数细分了这一点

如何衡量第三方脚本对页面的影响?
当您看到脚本引起问题时,请找出脚本的作用并确定您的网站是否需要它才能运行。如有必要,运行 A/B 测试以平衡其感知价值与其对关键用户参与度或性能指标的影响。
Lighthouse 启动时间审核
Lighthouse JavaScript 启动时间审核突出显示了脚本解析、编译或评估时间开销大的脚本。这可以帮助您识别 CPU 密集型第三方脚本。

Lighthouse 网络负载审核
Lighthouse 网络负载审核识别网络请求,包括减慢页面加载时间并使用户在移动数据上花费超出预期的第三方网络请求。

Chrome DevTools 网络请求阻止
Chrome DevTools 可让您查看当指定的脚本、样式表或其他资源不可用时页面的行为方式。这是通过网络请求阻止完成的,此功能可以帮助衡量从页面中删除各个第三方资源的影响。
要启用请求阻止,请右键单击“网络”面板中的任何请求,然后选择 阻止请求网址。“请求阻止”选项卡随后会在 DevTools 抽屉中显示,让您可以管理已阻止的请求。

Chrome DevTools 性能面板
Chrome DevTools 中的性能面板有助于识别页面 Web 性能的问题。
- 点击 录制。
- 加载您的页面。DevTools 显示一个瀑布图,表示您的网站花费加载时间的方式。
- 导航到“性能”面板底部的 自下而上。
- 点击 按产品分组,然后按加载时间对页面的第三方脚本进行排序。

要了解有关使用 Chrome DevTools 分析页面加载性能的更多信息,请参阅开始分析运行时性能。
以下是我们推荐的衡量第三方脚本影响的工作流程:
- 使用“网络”面板衡量加载页面所需的时间。
- 阻止负责您认为存在问题的第三方脚本的网址或域(有关识别开销大的脚本的指南,请参阅Chrome DevTools 性能面板)。
- 重新加载页面并再次测量加载时间。
- 为了获得更准确的数据,您可能需要至少测量三次加载时间。这考虑了一些第三方脚本在每次页面加载时获取不同资源的情况。为了帮助实现这一点,DevTools 性能面板支持多次录制。
使用 WebPageTest 衡量第三方脚本的影响
WebPageTest 支持阻止加载单个请求,以在 高级设置 > 阻止 中衡量其影响。使用此功能可指定要阻止的域列表,例如广告域。

我们建议使用以下工作流程来使用此功能:
- 在不阻止第三方的情况下测试页面。
- 在阻止某些第三方的情况下重复测试。
- 从您的 测试历史记录 中选择两个结果。
- 点击 比较。

下图显示了 WebPageTest 的胶片视图功能,比较了具有和不具有活动第三方资源的页面的加载顺序。我们建议检查针对各个第三方来源的测试,以确定哪些域对您页面的性能影响最大。

WebPageTest 还支持两个在 DNS 级别运行的命令来阻止域:
blockDomains
接受要阻止的域列表。- blockDomainsExcept 接受域列表并阻止列表中不包含的任何内容。
WebPageTest 还有一个单点故障 (SPOF) 选项卡,可让您模拟超时或完全无法加载资源。与域阻止不同,SPOF 会缓慢超时,这使其可用于测试当第三方服务负载过重或暂时不可用时页面的行为方式。

使用长任务检测开销大的 iframe
当第三方 iframe 中的脚本运行时间过长时,它们可能会阻止主线程并延迟其他任务。这些长任务可能会导致事件处理程序运行缓慢或帧丢失,从而使用户体验变差。
要检测 真实用户监控 (RUM) 的长任务,请使用 JavaScript PerformanceObserver API 来观察 longtask 条目。这些条目包含一个 attribution 属性,您可以使用该属性来确定哪个帧上下文导致了长任务。
以下代码将 longtask
条目记录到控制台,包括“开销大”iframe 的条目:
<script>
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// Attribution entry including "containerSrc":"https://example.com"
console.log(JSON.stringify(entry.attribution));
}
});
observer.observe({entryTypes: ['longtask']});
</script>
<!-- Imagine this is an iframe with expensive long tasks -->
<iframe src="https://example.com"></iframe>
要了解有关监控长任务的更多信息,请参阅以用户为中心的性能指标。
如何高效加载第三方脚本?
如果第三方脚本减慢了页面加载速度,您有几个选项可以提高性能:
- 使用
async
或defer
属性加载脚本,以避免阻止文档解析。 - 如果第三方服务器速度缓慢,请考虑自行托管脚本。
- 如果脚本没有为您的网站增加明显的价值,请将其删除。
- 使用 资源提示,例如
<link rel=preconnect>
或<link rel=dns-prefetch>
,对托管第三方脚本的域执行 DNS 查找。
使用 async
或 defer
JavaScript 执行会阻止解析器。当浏览器遇到脚本时,它必须暂停 DOM 构建,将脚本传递给 JavaScript 引擎,并允许脚本执行,然后才能继续进行 DOM 构建。
async
和 defer
属性会更改此行为,如下所示:
async
使浏览器异步下载脚本,同时继续解析 HTML 文档。当脚本完成下载时,解析会被阻止,同时脚本执行。defer
使浏览器异步下载脚本,同时继续解析 HTML 文档,然后在文档解析完成后等待运行脚本。
始终对第三方脚本使用 async
或 defer
,除非脚本对于关键渲染路径是必需的。如果脚本需要在加载过程中较早运行(例如对于某些分析脚本),请使用 async
。对于不太重要的资源(例如在页面上比用户最初看到的更低位置渲染的视频),请使用 defer
。
如果性能是您的主要考虑因素,我们建议等到页面关键内容加载后,再添加异步脚本。我们不建议对诸如 jQuery 之类的基本库使用 async
。
某些脚本必须在没有 async
或 defer
的情况下加载,尤其是那些对您的网站至关重要的脚本。这些脚本包括您的网站离不开的 UI 库或内容分发网络 (CDN) 框架。
如果异步加载,其他脚本就无法正常工作。检查您正在使用的任何脚本的文档,并将任何无法异步加载的脚本替换为可以异步加载的替代脚本。请注意,即使某些第三方脚本异步运行的效果也同样好,但他们仍建议同步运行脚本。
请记住,async
并不能解决所有问题。如果您的页面包含大量脚本(例如用于广告目的的跟踪脚本),则异步加载它们并不能阻止它们减慢页面加载速度。
使用资源提示来缩短连接建立时间
建立与第三方来源的连接可能需要很长时间,尤其是在慢速网络上,因为网络请求具有多个复杂的组件,包括 DNS 查找和重定向。您可以使用资源提示,例如 ,在页面加载过程的早期对托管第三方脚本的域执行 DNS 查找,以便稍后可以更快地进行其余的网络请求
<link rel="dns-prefetch" href="http://example.com" />
如果您连接的第三方域使用 HTTPS,您还可以使用 ,它既执行 DNS 查找,又解析 TCP 往返行程并处理 TLS 协商。其他这些步骤可能非常慢,因为它们涉及验证 SSL 证书,因此预连接可以大大缩短加载时间。
<link rel="preconnect" href="https://cdn.example.com" />
使用 iframe “沙盒化”脚本
如果您将第三方脚本直接加载到 iframe 中,它不会阻止主页面的执行。AMP 使用此方法将 JavaScript 排除在关键路径之外。请注意,此方法仍然会阻止 onload
事件,因此请尽量不要将关键功能附加到 onload
。
Chrome 还支持 Permissions Policy(以前称为 Feature Policy),这是一组策略,允许开发者有选择地禁用对某些浏览器功能的访问。您可以使用它来防止第三方内容将不需要的行为引入到网站。
自行托管第三方脚本
如果您想更好地控制关键脚本的加载方式,例如为了缩短 DNS 时间或改进 HTTP 缓存标头,您或许可以自行托管它。
但是,自行托管也存在自身的问题,尤其是在更新脚本方面。自行托管的脚本不会获得针对 API 更改或安全修复的自动更新,这可能会导致收入损失或安全问题,直到您可以手动更新脚本为止。
作为替代方案,您可以使用 Service Worker 缓存第三方脚本,以便更好地控制从网络获取脚本的频率。您还可以使用 Service Worker 创建加载策略,以限制非必要的第三方请求,直到您的页面到达关键用户时刻。
A/B 测试较小的用户样本
A/B 测试(或拆分测试)是一种用于试验页面两个版本以分析用户体验和行为的技术。它使页面版本可供您网站流量的不同样本使用,并从分析中确定哪个版本提供更好的转化率。
但是,从设计上来说,A/B 测试会延迟渲染以决定哪个实验需要处于活动状态。JavaScript 通常用于检查是否有任何用户属于 A/B 测试实验,然后启用正确的变体。即使对于不属于实验的用户,此过程也可能会使体验变差。
为了加快页面渲染速度,我们建议将 A/B 测试脚本发送到较小的用户群样本,并在服务器端运行决定要显示哪个页面版本的代码。
延迟加载第三方资源
当构造不佳时,嵌入式第三方资源(如广告和视频)可能是页面速度缓慢的主要原因。延迟加载可用于仅在必要时加载嵌入式资源,例如,等待在页面页脚中投放广告,直到用户滚动到足以看到它们的位置。您还可以在主要页面内容加载后但在用户可能与页面交互之前延迟加载第三方内容。

在延迟加载资源时要小心,因为它通常涉及可能受到不稳定的网络连接影响的 JavaScript 代码。
DoubleClick 在其 官方文档 中提供了有关如何延迟加载广告的指南。
使用 Intersection Observer 进行高效的延迟加载
从历史上看,出于延迟加载目的检测元素是否在视口中可见的方法容易出错,并且通常会降低浏览器的速度。这些低效的方法通常会侦听 scroll 或 resize 事件,然后使用 DOM API(如 getBoundingClientRect())来计算元素相对于视口的位置。
IntersectionObserver 是一个浏览器 API,它使页面所有者能够有效地检测到观察到的元素何时进入或离开浏览器的视口。LazySizes 也对 IntersectionObserver 具有可选支持。
延迟加载分析
如果您延迟加载分析脚本的时间过长,您可能会错过有价值的分析数据。幸运的是,有一些策略可用于延迟初始化分析,同时保留早期的页面加载数据。
Phil Walton 的博文 我在构建的每个网站上使用的 Google Analytics 设置 涵盖了 Google Analytics 的一种此类策略。
安全地加载第三方脚本
本节提供有关尽可能安全地加载第三方脚本的指南。
避免使用 document.write()
第三方脚本,尤其是较旧的服务的脚本,有时会使用 document.write()
来注入和加载脚本。这是一个问题,因为 document.write()
的行为不一致,并且其故障难以调试。
解决 document.write() 问题的修复方法是不使用它。在 Chrome 53 及更高版本中,Chrome DevTools 会将有关 document.write()
的问题用法的警告记录到控制台中。

document.write()
用法。如果您收到此错误,则可以通过查找发送到浏览器的 HTTP 标头来检查您的网站中是否使用了 document.write()
。Lighthouse 还可以突出显示任何仍在使用 document.write()
的第三方脚本。

document.write()
。谨慎使用代码管理器
代码是一个代码片段,数字营销团队可以使用它来收集数据、设置 Cookie 或将社交媒体小部件等第三方内容集成到网站中。这些代码会将网络请求、JavaScript 依赖项和其他资源添加到您的页面,这些资源可能会影响其性能,并且随着添加的代码越来越多,最大限度地减少用户受到的影响变得更加困难。
为了保持页面快速加载,我们建议使用代码管理器,例如 Google Tag Manager (GTM)。GTM 允许您异步部署代码,以便它们不会阻止彼此加载,减少浏览器需要执行代码的网络调用次数,并在其 数据层 UI 中收集代码数据。
使用代码管理器的风险
尽管代码管理器旨在简化页面加载,但粗心使用它们反而会降低页面加载速度,原因如下:
- 代码管理器中过多的代码和 自动事件侦听器会导致浏览器发出比原本需要的更多的网络请求,并降低您的代码快速响应事件的能力。
- 任何具有凭据和访问权限的人都可以在您的代码管理器中添加 JavaScript。这不仅会增加加载页面所需的开销大的网络请求数量,而且还可能因不必要的脚本而带来安全风险和其他性能问题。为了降低这些风险,我们建议限制对代码管理器的访问。
避免污染全局作用域的脚本
第三方脚本的行为方式可能会以各种意想不到的方式破坏您的页面:
- 加载 JavaScript 依赖项的脚本可能会使用与您的代码交互不良的代码污染全局作用域。
- 意外的更新可能会导致重大更改。
- 第三方代码可以在传输过程中被修改,从而在页面的测试和部署之间表现不同。
我们建议定期审核您加载的第三方脚本,以检查不良行为者。您还可以实施自我测试、子资源完整性和第三方代码的安全传输,以确保您的页面安全。
缓解策略
以下是一些大规模策略,用于最大限度地减少第三方脚本对您网站性能和安全性的影响:
沙盒化:考虑在具有
sandbox
属性的 iframe 中运行第三方脚本,以限制脚本可用的操作。内容安全策略 (CSP):您可以在服务器响应中使用 HTTP 标头来定义您网站的受信任脚本行为,并检测和缓解某些攻击(例如跨站脚本 (XSS))的影响。
以下是如何使用 CSP 的 script-src 指令来指定页面允许的 JavaScript 来源的示例:
// Given this CSP header Content-Security-Policy: script-src
https://example.com/ // The following third-party script will not be loaded or
executed
<script src="https://not-example.com/js/library.js"></script>
延伸阅读
要了解有关优化第三方 Javascript 的更多信息,我们建议您阅读以下内容:
- 性能和弹性:压力测试第三方
- 使用 JavaScript 添加互动性
- 第三方脚本的潜在危险
- 第三方脚本如何在 Web 上成为性能良好的公民
- 为什么速度很重要 - CSS Wizardry
- JavaScript 供应链悖论:SRI、CSP 和对第三方库的信任
- 第三方 CSS 不安全
感谢 Kenji Baheux、Jeremy Wagner、Pat Meenan、Philip Walton、Jeff Posnick 和 Cheney Tsai 的审核。