第三方 JavaScript影响性能怎么办

2 阅读9分钟

第三方 JavaScript 性能

了解第三方 JavaScript 对性能的影响,以及您可以采取哪些措施来防止其拖慢网站速度。

第三方 JavaScript 通常是指您的网站中嵌入的具有以下特征的脚本:

  • 非您创作
  • 由第三方服务器投放

网站会将这些脚本用于各种目的,包括:

  • 社交分享按钮
  • 视频播放器嵌入
  • 聊天服务
  • 广告 iframe
  • 分析和指标脚本
  • 用于实验的 A/B 测试脚本
  • 辅助库(如日期格式设置、动画和功能库)

第三方脚本可以提供强大的功能,但这还远远不够。它们还会影响隐私、安全性和页面行为,并且尤其会给性能带来问题。

性能

如果存在大量的JavaScript,就会降低性能。但是,由于第三方 JavaScript 通常不在您的控制范围之内,因此可能会带来其他问题。

网络

设置连接需要时间,而向多个服务器发送过多请求会导致速度下降。对于安全连接而言,这一时间会更长,因为安全连接可能会涉及 DNS 查找、重定向以及到处理用户请求的最终服务器多次往返。

第三方脚本往往会增加网络开销,例如:

  • 触发其他网络请求
  • 拉取未经优化的图片和视频
  • HTTP 缓存不足,这会强制频繁提取网络资源
  • 资源的服务器压缩不足
  • 由不同第三方嵌入提取的框架和库的多个实例

渲染

第三方 JavaScript 的加载方式非常重要。如果是在关键渲染路径中同步完成,则会延迟对文档其余部分的解析。

关键术语关键渲染路径包含浏览器为了显示第一个屏幕上的内容而需要的所有资源。

如果第三方出现服务器问题且未能投放资源,系统就会阻止呈现,直到请求超时(时长介于 10 到 80 秒之间)。

注意 :[A/B 测试脚本]也常常会造成呈现延迟。大多数测试都会在完成处理之前阻止内容显示,即使是异步 A/B 测试脚本也是如此。

解决办法

通常不可避免地要使用第三方 JavaScript,但您可以采取以下措施来最大限度地减少负面影响:

  • 在选择第三方资源时,请青睐发送最少代码量且仍能为您提供所需功能的资源。
  • 不要使用两家不同供应商的相同功能。您可能不需要两个跟踪代码管理器或两个分析平台。
  • 定期审核并清理多余的第三方脚本。

高效加载第三方 JavaScript

 bookmark_border

避免使用第三方脚本来缩短加载时间并改善用户体验,避免常见的隐患。

如果第三方脚本[减慢了]网页加载速度,您可以通过以下两种方法改善性能:

  • 如果这对您的网站没有明显的价值,请将其移除。
  • 优化加载过程。

此博文介绍了如何使用以下方法优化第三方脚本的加载过程:

  1. 在 <script> 标记中使用 async 或 defer 属性
  2. 尽早与所需源站建立连接
  3. 延迟加载
  4. 优化第三方脚本的提供方式

使用 async 或 defer

由于同步脚本会延迟 DOM 的构建和呈现,因此您应始终以异步方式加载第三方脚本,除非相应脚本必须先运行才能呈现网页。

async 和 defer 属性会告知浏览器,在后台加载脚本时可能会继续解析 HTML,然后在加载后执行脚本。这样,脚本下载就不会阻止 DOM 构建和网页呈现。其结果是,在所有脚本加载完毕之前,用户就可以看到网页。

<script async src="script.js">

<script defer src="script.js">

async 和 defer 之间的区别在于它们开始执行脚本时。

async

具有 async 属性的脚本会在下载完成之后、窗口的 load 事件之前第一次执行。这意味着,async 脚本有可能(并且很有可能)不会按照它们在 HTML 中的显示顺序执行。这也意味着,如果它们在解析器仍在工作时完成下载,则可能会中断 DOM 构建。

具有异步属性的解析器阻止脚本示意图

defer

具有 defer 属性的脚本会在 HTML 解析全部完成后、DOMContentLoaded 事件之前执行。defer 可保证脚本将按照它们在 HTML 中显示的顺序执行,并且不会阻止解析器。

包含具有 defer 属性的脚本的解析器流程示意图

  • 如果务必在加载过程中提前运行该脚本,请使用 async
  • 对不太重要的资源使用 defer。非首屏视频播放器。

使用这些属性可以显著加快网页加载速度。例如,Telegraph 最近推迟了所有脚本(包括广告和分析),将广告加载时间平均缩短了 4 秒。

注意 :通常,分析脚本通常会提前加载,以免错过任何有价值的分析数据。幸运的是,存在延迟初始化分析的模式,同时保留早期网页加载数据。

尽早与所需源站建立连接

通过尽早与重要的第三方源建立连接,您可以节省 100 到 500 毫秒的时间。

以下两种 <link> 类型可助您一臂之力:

  • preconnect
  • dns-prefetch

preconnect

<link rel="preconnect"> 会告知浏览器您的网页打算与另一个源建立连接,您希望尽快开始该过程。当用户从预先连接的来源请求资源时,系统会立即开始下载。

<link rel="preconnect" href="https://cdn.example.com">

注意 :请仅预先连接到您很快要使用的关键网域,因为浏览器会在 10 秒内关闭所有未使用的连接。不必要的预连接可能会延误其他重要资源,因此请限制预连接网域的数量并测试预连接造成的影响

dns-prefetch

<link rel="dns-prefetch> 会处理由 <link rel="preconnect"> 处理的一小部分内容。建立连接涉及 DNS 查找和 TCP 握手,而对于安全源,则涉及 TLS 协商。dns-prefetch 指示浏览器仅在特定网域的 DNS 被明确调用之前进行解析。

preconnect 提示最适合仅用于最关键的连接;对于不太重要的第三方网域,请使用 <link rel=dns-prefetch>

<link rel="dns-prefetch" href="http://example.com">

浏览器对 dns-prefetch 的支持与对 preconnect 支持略有不同,因此,对于不支持 preconnect 的浏览器,dns-prefetch 可作为后备方案。请使用单独的链接标记安全地植入代码:

<link rel="preconnect" href="http://example.com">
<link rel="dns-prefetch" href="http://example.com">

延迟加载第三方资源

如果构建不当,嵌入式第三方资源可能会拖慢网页速度。如果它们不重要或位于非首屏(即用户必须滚动浏览时),则延迟加载是提高网页速度和绘制指标的好方法。这样,用户就可以更快地看到主页面内容,并获得更好的体验。

移动设备上显示的网页示意图,其中包含可滚动内容延伸到屏幕以外。非首屏内容因尚未加载而饱和度较低。

一种有效的方法是在主页面内容加载后延迟加载第三方内容。广告非常适合采用这种方法。

对许多网站来说,广告是重要的收入来源,但用户是为了观看内容而来。通过延迟加载广告和更快地提供主要内容,您可以提高广告的总体可见度百分比。例如,MediaVine 改用延迟加载广告后,网页加载速度提升了 200%。DoubleClick 的官方文档中提供了有关如何延迟加载广告的指导。

另一种方法是仅在用户向下滚动到网页的相应部分时加载第三方内容。

Intersection Observer 是一种浏览器 API,可有效检测元素何时进入或退出浏览器视口,并可用于实现这种技术。lazysizes 是一种用于延迟加载图片和 iframes 的热门 JavaScript 库。它支持嵌入式 YouTube 内容和微件。它还提供对 IntersectionObserver 的可选支持

注意 :使用 JavaScript 延迟加载资源时,请务必小心谨慎。如果 JavaScript 加载失败(可能是由于不稳定的网络状况),则根本无法加载您的资源。

使用 loading 属性延迟加载图片和 iframe 是 JavaScript 技术的绝佳替代方案,并且最近已在 Chrome 76 中推出!

优化第三方脚本的提供方式

第三方 CDN 托管

第三方供应商通常会提供其托管的 JavaScript 文件的网址(通常在内容分发网络 (CDN) 上)。这种方法的优势在于,您只需复制并粘贴网址即可快速上手,且没有维护开销。第三方供应商负责处理服务器配置和脚本更新。

但是,由于它们与您的其余资源不在同一来源,因此从公共 CDN 加载文件会产生网络费用。浏览器需要执行 DNS 查找、建立新的 HTTP 连接,并在安全源上与供应商的服务器执行 SSL 握手。

使用来自第三方服务器的文件时,您几乎无法控制缓存。依赖其他人的缓存策略可能导致过于频繁地从网络中重新获取不必要的脚本。

自行托管第三方脚本

通过自行托管第三方脚本,您可以更好地控制脚本的加载过程。通过自行托管,您可以:

  • 减少 DNS 查找和往返时间。
  • 改进 HTTP 缓存标头。
  • 利用 HTTP/2 或更新版本的 HTTP/3。

例如,Casper 通过自行托管一个 A/B 测试脚本,成功将加载时间缩短了 1.7 秒

但自行托管有一个重大缺点:当 API 更改或安全修复程序发生时,脚本可能会过时,并且无法自动更新。

注意 :手动更新脚本可能会给开发过程增加大量开销,而且您可能会错过重要的更新。如果您不使用 CDN 托管来传送所有资源,那么还会错过边缘缓存,而且必须优化服务器的压缩。

使用 Service Worker 缓存来自第三方服务器的脚本

除自托管以外,您还可以使用 Service Worker 缓存来自第三方服务器的脚本,从而更好地控制缓存,同时仍能享受第三方 CDN 的优势。这样一来,您就可以控制从网络中重新提取脚本的频率,并制定加载策略来限制对非必要的第三方资源的请求,直到网页进入关键用户时刻为止。在这种情况下,使用 preconnect 尽早建立连接还可以一定程度上降低网络费用。