自托管第三方资源:好的、坏的、丑陋的

近年来,越来越多的优化前端项目的平台提供了自托管或代理第三方资源的机会。 Akamai 允许您设置 具体参数 用于自行生成的 URL。 Cloudflare 拥有 Edge Workers 技术。 法斯特嗪可以 改写 页面上的 URL,以便它们指向位于网站主域上的第三方资源。

自托管第三方资源:好的、坏的、丑陋的

如果您知道项目中使用的第三方服务不会经常更改,并且将它们交付给客户的过程可以改进,那么您可能正在考虑代理此类服务。 通过这种方法,您可以很好地使这些资源更接近您的用户,并在客户端获得对其缓存的更完整的控制。 此外,这还可以保护用户免受第三方服务“崩溃”或其性能下降造成的麻烦。

好:性能提高

自托管他人的资源可以以非常明显的方式提高性能。 浏览器不需要再次访问DNS,不需要与第三方域建立TCP连接和执行TLS握手。 通过比较以下两个图,您可以了解自托管其他人的资源如何影响性能。

自托管第三方资源:好的、坏的、丑陋的
第三方资源是从外部来源下载的(取自 )

自托管第三方资源:好的、坏的、丑陋的
第三方资源与网站其他材料存储在同一位置(取自 )

这种情况也得到了改善,因为浏览器将使用对来自已与主域建立的 HTTP/2 连接的数据进行多路复用和优先级处理的能力。

如果您不托管第三方资源,那么由于它们将从与主域不同的域加载,因此无法对它们进行优先级排序。 这将导致它们相互竞争客户端的带宽。 这可能会导致对于构建页面至关重要的内容的加载时间比理想情况下可实现的时间长得多。 这里 有关 HTTP/2 优先级的讨论很好地解释了这一切。

可以假设在外部资源链接中使用属性 preconnect 将有助于解决问题。 然而,如果这些通往不同域的链接太多,实际上可能会在最关键的时刻使通信线路超载。

如果您自己托管第三方资源,您可以控制如何将这些资源提供给客户端。 也就是说,我们正在讨论以下内容:

  • 您可以确保使用最适合每个浏览器的数据压缩算法(Brotli/gzip)。
  • 您可以增加通常不是特别长的资源的缓存时间,即使是最知名的提供商也是如此(例如,GA 标记的相应值设置为 30 分钟)。

您甚至可以通过将相关内容合并到缓存管理策略(URL 哈希、版本控制等)中,将资源的 TTL 延长至一年。 我们下面会谈到这一点。

▍防止第三方服务运行中断或关闭

自托管第三方资源的另一个有趣的方面是,它允许您减轻与第三方服务中断相关的风险。 假设您正在使用的第三方 A/B 测试解决方案是作为在页面的头部加载的阻止脚本实现的。 该脚本加载缓慢。 如果相应的脚本加载失败,页面将为空。 如果加载时间很长,页面的显示就会有很长的延迟。 或者,假设该项目使用从第三方 CDN 资源下载的库。 让我们想象一下该资源在某个国家遇到了故障或被阻止。 这样的情况会导致违反网站逻辑。

要了解当某些外部服务不可用时您的站点如何工作,您可以使用 SPOF 部分 网页测试.org.

自托管第三方资源:好的、坏的、丑陋的
pagetest.org 上的 SPOF 部分

▍浏览器中缓存素材的问题怎么办? (提示:这是一个神话)

您可能认为使用公共 CDN 会自动带来更好的资源性能,因为这些服务拥有相当高质量的网络并且分布在世界各地。 但实际上一切都有点复杂。

假设我们有几个不同的网站:website1.com、website2.com、website3.com。 所有这些站点都使用 jQuery 库。 我们使用 CDN 将其连接到它们,例如 - googleapis.com。 您可以期望浏览器下载并缓存该库一次,然后在所有三个站点上使用它。 这可以减少网络负载。 也许这可以让您在某个地方省钱并帮助提高资源性能。 从实际角度来看,一切看起来都不一样。 例如,Safari 有一个功能称为 智能跟踪预防:缓存根据文档来源和第三方资源来源采用双键。 这里 关于这个主题的好文章。

旧研究 雅虎 и Facebook,以及最近的 研究 Paul Calvano 表示,资源在浏览器缓存中存储的时间并不像我们预期的那么长:“项目自己的资源和第三方资源的缓存时间之间存在严重差距。 我们正在谈论 CSS 和网络字体。 即95%的原生字体的缓存寿命超过一周,而50%的第三方字体的缓存寿命不到一周! 这为网络开发人员提供了一个令人信服的理由来自行托管字体文件!”

因此,如果您托管其他人的内容,您将不会注意到浏览器缓存导致的任何性能问题。

现在我们已经介绍了第三方自托管的优势,接下来我们来谈谈如何区分这种方法的好坏。

坏处:细节决定成败

如果不确保正确缓存此类资源,则无法自动将第三方资源移至您自己的域。

这里的主要问题之一是缓存时间。 例如,版本信息包含在第三方脚本名称中,如下所示: jquery-3.4.1.js。 这样的文件将来不会改变,因此不会导致其缓存出现任何问题。

但是,如果在处理文件时未使用某些版本控制方案,则缓存的脚本(其内容发生变化而文件名保持不变)可能会过时。 这可能是一个严重的问题,因为它不允许将自动安全补丁添加到客户端需要尽快接收的脚本中。 开发人员必须努力更新缓存中的此类脚本。 此外,这可能会导致应用程序失败,因为客户端上使用的缓存代码与项目的服务器部分设计的最新版本的代码不同。

确实,如果我们谈论经常更新的材料(标签管理器、A/B 测试解决方案),那么使用 CDN 工具缓存它们是一项可以解决的任务,但要复杂得多。 Commanders Act(一种标签管理解决方案)等服务在发布新版本时使用 Webhooks。 这使您能够强制刷新 CDN 上的缓存,或者更好的是,能够强制更新哈希值或 URL。

▍向客户自适应地交付材料

另外,当我们谈论缓存时,我们需要考虑到CDN上使用的缓存设置可能不适合某些第三方资源。 例如,此类资源可以使用用户代理嗅探(自适应服务)技术来为特定浏览器提供专门针对这些浏览器优化的内容版本。 这些技术依赖正则表达式或 HTTP 头信息数据库来确定浏览器的功能。 User-Agent。 一旦他们知道自己正在使用哪种浏览器,他们就会为其提供专门设计的材料。

在这里你可以记住两项服务。 第一个是 googlefonts.com。 第二个是polyfill.io。 Google Fonts 服务根据浏览器的功能,为特定资源提供各种 CSS 代码(使用 woff2 资源提供链接) unicode-range).

以下是从不同浏览器进行的几个 Google Fonts 查询的结果。

自托管第三方资源:好的、坏的、丑陋的
Chrome 中的 Google Fonts 查询结果

自托管第三方资源:好的、坏的、丑陋的
从 IE10 执行的 Google Fonts 查询的结果

Polyfill.io 只为浏览器提供所需的 polyfill。 这样做是出于性能原因。

例如,让我们看一下如果从不同的浏览器运行以下请求会发生什么: https://polyfill.io/v3/polyfill.js?features=default

响应从 IE10 执行的此类请求,将收到 34 KB 的数据。 从 Chrome 执行的答案将为空。

愤怒:一些隐私考虑

这一点按顺序排在最后,但也同样重要。 关键是,在项目主域或其子域上自托管第三方资源可能会危害用户的隐私并对主 Web 项目产生负面影响。

如果您的 CDN 系统配置不正确,您最终可能会将域的 cookie 发送到第三方服务。 如果没有在 CDN 级别组织适当的过滤,那么您的会话 cookie 通常无法在 JavaScript 中使用(使用 httponly),可能会发送到国外主机。

这正是 Eulerian 或 Criteo 等跟踪器可能发生的情况。 第三方跟踪器可能已在 cookie 中设置了唯一标识符。 如果它们是网站材料的一部分,那么当用户使用不同的网络资源时,他们可以自行读取标识符。

如今,大多数浏览器都包含针对此类跟踪器行为的保护措施。 因此,追踪器现在使用技术 CNAME 伪装,伪装成自己的脚本用于各种项目。 也就是说,跟踪器允许网站所有者将 CNAME 添加到特定域的设置中,该域的地址通常看起来像一组随机字符。

尽管不建议让网站 cookie 对所有子域都可用(例如 - *.website.com),但许多网站都会这样做。 在这种情况下,此类 cookie 会自动发送到伪装的第三方跟踪器。 结果,我们不能再谈论任何隐私。

此外,HTTP 标头也会发生同样的情况 客户提示,它们仅发送到主域,因为它们可用于创建 数字指纹 用户。 确保您使用的 CDN 服务正确过滤这些标头。

结果

如果您近期打算实现第三方资源自托管,我给您一些建议:

  • 托管您最重要的 JS 库、字体和 CSS 文件。 这将降低由于第三方服务故障而导致站点重要资源不可用而导致站点故障或性能下降的风险。
  • 在 CDN 上缓存第三方资源之前,请确保在命名其文件时使用某种版本控制系统,或者您可以在发布新版本时通过手动或自动重置 CDN 缓存来管理这些资源的生命周期。剧本。
  • 请务必小心您的 CDN、代理服务器和缓存设置。 这将允许您防止向您的项目或标头发送 cookie Client-Hints 第三方服务。

亲爱的读者! 您是否在您的服务器上托管对您的项目运营极其重要的其他人的资料?

自托管第三方资源:好的、坏的、丑陋的
自托管第三方资源:好的、坏的、丑陋的

来源: habr.com

添加评论