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

如果您知道项目中使用的第三方服务不会经常更改,并且可以改善向客户交付第三方服务的过程,那么您可能会考虑代理此类服务。 使用这种方法,您可以将这些资源“拉近”到用户附近,并在客户端上获得对其缓存的更多控制。 此外,这还使您可以保护用户免受第三方服务“降级”或性能下降所引起的麻烦。
良好:提高生产力
他人资源的自我托管以非常明显的方式提高了性能。 浏览器不需要再次访问DNS,也不需要建立TCP连接并在第三方域上执行TLS握手。 通过比较以下两个数字,可以看出独立托管其他人的资源如何影响生产力。
第三方资源是从外部资源下载的( 从此处获取 )第三方资源与其余站点材料存储在同一位置( 从此处获取 )浏览器将使用已与主域建立的HTTP / 2连接数据的复用和优先级排序功能,从而改善了这种情况。
如果您不托管第三方资源,则由于将从非主要资源的域中下载它们,因此无法确定它们的优先级。 这将导致它们彼此竞争客户端的带宽。 这可能导致这样的事实,即对于形成页面至关重要的材料的加载时间将比在理想情况下可获得的时间长得多。
这是关于HTTP / 2优先级的讨论,很好地解释了所有这些。
可以假定在到外部资源的链接中使用
preconnect
属性将有助于解决问题。 但是,如果到各个域的此类链接过多,则实际上可能会在最关键的时刻使通信线路过载。
如果您自己托管第三方资源,则可以控制如何将这些资源分配给客户端。 即,我们正在谈论以下内容:
- 您可以确保应用最适合每种浏览器的数据压缩算法(Brotli / gzip)。
- 您可以增加资源的缓存时间,即使对于最知名的提供程序来说,资源的缓存时间通常也不是很大(例如,GA标签的相应值设置为30分钟)。
您甚至可以通过在缓存管理策略中包括适当的材料(URL哈希,版本控制等)来将资源的TTL延长至例如一年。 我们将在下面讨论。
▍防止第三方服务运行中断或断开连接
独立托管第三方资源的另一个有趣的方面是,这使您可以减轻与第三方服务运行中断相关的风险。 假设您的A / B测试第三方解决方案是作为阻止脚本加载到页面的页眉部分中的。 该脚本加载缓慢。 如果相应的脚本无法加载,则页面将为空。 如果加载时间很长,该页面将出现较长的延迟。 或者,假设项目使用从第三方CDN资源加载的库。 想象一下,该资源在某个国家/地区崩溃或被阻止。 这种情况将导致违反网站逻辑。
为了找出您的网站在某些外部服务无法访问的情况下的工作方式,您可以使用
webpagetest.org上的SPOF部分。
webpagetest.org上的SPOF部分如何处理浏览器的缓存问题? (提示:这是一个神话)
您可能会认为,使用公开可用的CDN会自动导致更好的资源性能,因为这些服务具有相当好的网络并且分布在世界各地。 但是实际上,所有事情都有些复杂。
假设我们有几个不同的站点:website1.com,website2.com,website3.com。 所有这些站点都使用jQuery库。 我们使用CDN将其连接到他们,例如googleapis.com。 您可以期望浏览器一次下载并缓存该库,然后在使用所有三个站点时使用它。 这样可以减少网络上的负载。 也许这将在某处节省金钱并有助于提高资源生产率。 从实际的角度来看,一切看起来都不同。 例如,Safari实现了一项称为“
智能跟踪预防”的功能:缓存基于文档的来源和第三方资源的来源使用双键。
这是一篇关于该主题
的好文章。
雅虎和
Facebook的旧研究,以及保罗·卡尔瓦诺
( Paul Calvano)的最新
研究表明,只要我们期望的那样,资源就不会存储在浏览器缓存中:“我们自己和第三方项目资源的缓存时间之间存在严重差距。 这是关于CSS和网络字体的。 即,他们自己的字体的95%的缓存期超过一周,而第三方字体的50%的缓存期不到一周! 这为Web开发人员提供了自托管字体文件的充分理由!”
因此,如果您托管其他人的资料,您将不会注意到由浏览器缓存引起的性能问题。
现在,我们已经研究了自托管第三方资源的优点,下面我们来讨论如何区分这种方法的良好实现与不良方法。
坏:细节决定成败
如果不注意正确地缓存此类资源,则无法自动执行将第三方资源移至您自己的域的操作。
这里的主要问题之一是缓存时间。 例如,版本信息包含在第三方脚本名称中,例如:
jquery-3.4.1.js
。 这样的文件将来不会更改,因此不会导致其缓存出现任何问题。
但是,如果在处理文件时未应用某个版本控制方案,则缓存的脚本(其内容在文件名不变时会更改)会过时。 这可能会成为一个严重的问题,因为例如,它不允许将安全修复程序自动引入客户端应尽快接收的脚本中。 开发人员将不得不努力更新缓存中的此类脚本。 此外,这可能会导致应用程序崩溃,原因是缓存中客户端上使用的代码与设计项目的服务器部分的最新版本的代码不同。
没错,如果我们谈论的是经常更新的材料(标签管理器,A / B测试解决方案),那么使用CDN缓存它们是可以解决的任务,但它已经复杂得多。 诸如《指挥官法》,标签管理解决方案之类的服务使用Web挂钩发布新版本。 这样就可以在CDN上组织缓存刷新,甚至可以更好地调用哈希更新或URL版本。
▍自适应地向客户交付材料
另外,在谈论缓存时,我们还必须考虑到CDN上使用的缓存设置可能不适用于某些第三方资源这一事实。 例如,这样的资源可以使用用户代理嗅探技术,自适应服务,以便提供针对这些浏览器专门优化的材料的特定浏览器版本。 为了找出浏览器的功能,这些技术依赖于正则表达式或收集有关
User-Agent
HTTP标头信息的数据库。 在了解了他们正在使用哪个浏览器之后,他们会为其提供设计的材料。
在这里您可以调用两项服务。 第一个是googlefonts.com。 第二个是polyfill.io。 Google字体服务根据浏览器的功能为特定资源提供了各种CSS代码(使用
unicode-range
提供指向woff2资源的链接)。
以下是使用不同浏览器进行的几次Google字体查询的结果。
Chrome字体查询结果从IE10取得的Google字体查询结果Polyfill.io仅向浏览器提供所需的那些polyfill。 这样做是出于性能原因。
例如,看看从不同的浏览器运行以下请求会发生什么:
https :
//polyfill.io/v3/polyfill.js?features=default响应IE10的这种请求,将出现34 Kb的数据。 由Chrome制成的答案将为空。
生气:一些隐私注意事项
该项目排在最后,但重要性不高。 关键是,在项目的主域或其子域上独立托管第三方资源会损害用户的隐私,并对主Web项目产生不利影响。
如果您的CDN系统配置不正确,则可能最终会将Cookie从您的域发送到第三方服务。 如果未在CDN级别上组织适当的过滤,则可以将在正常情况下不能在JavaScript(带有
httponly
属性)中使用的会话cookie发送到外部主机。
这正是Eulerian或Criteo等追踪器可能发生的情况。 第三方跟踪器可以在Cookie中设置唯一标识符。 如果它们是网站材料的一部分,则在用户使用其他Web资源进行工作时,他们可以自行决定读取标识符。
如今,大多数浏览器都包含针对此类跟踪器行为的保护。 结果,跟踪程序现在使用
CNAME隐藏技术,伪装成自己的脚本来处理各种项目。 即,跟踪器为网站所有者提供了将CNAME添加到其某个域的域设置中的功能,该域的地址通常看起来像是随机字符集。
尽管不建议所有子域(例如* .website.com)都可以访问该网站的cookie,但是许多网站都这样做。 在这种情况下,此类Cookie会自动发送到伪装的第三方跟踪器。 因此,您不能再谈论任何隐私。
此外,
Client-Hints HTTP标头也发生了同样的事情,它们仅发送到主域,因为它们可用于创建用户的
数字指纹 。 请确保您使用的CDN服务正确过滤了此类标头。
总结
如果您打算很快引入独立托管的第三方资源-让我给您一些提示:
- 托管最重要的JS库,字体和CSS文件。 由于第三方服务导致站点无法使用的重要资源这一事实,这将减少站点故障或性能降低的风险。
- 在将第三方资源缓存在CDN上之前,请确保在命名它们的文件时使用版本控制系统,或者在发布新版本的脚本时通过手动或自动刷新CDN缓存来控制这些资源的生命周期。
- 请特别注意CDN,代理服务器,缓存的设置。 这将使您能够防止将项目的Cookie或
Client-Hints
标头发送到第三方服务。
亲爱的读者们! 您是否在服务器上发布了对您的项目非常重要的其他人的材料?
