资源预加载可能会拖慢网站速度

程序员咋不秃头 2025-04-02 02:06:44

前言

探讨了资源预取(prefetching)可能导致网站加载速度变慢的问题,并提供了解决方案。

预加载(Prefetching)本应提升性能,但有时却可能延迟网站的加载速度。

本文将介绍资源预加载的优势、它可能带来的性能问题,以及如何应对这些问题。

资源预加载的作用

预加载是一种网页性能优化技术,它会提前加载可能需要的资源,以加快后续访问速度。

例如,当用户访问你的首页时,你可以预加载登录页面或定价页面所需的代码。这样,当用户真正进入这些页面时,资源已经准备就绪,加载速度会更快。

要预加载资源,可以在 HTML 代码中添加一个预加载链接标签,例如:

<linkrel="prefetch"as="style"href="page-2.css"/>预加载请求的优先级

预加载的资源并不是立刻需要的,因此它们应该在后台悄悄加载。Google 在 web.dev 上对此进行了说明:

浏览器会将所有预加载提示排队,并在空闲时请求这些资源。

预加载的请求被标记为 “最低” 优先级,因此它们不会与当前页面所需的资源争夺带宽。

预加载请求过早导致的带宽竞争

然而,在分析网站资源加载的请求瀑布图时,我们发现预加载请求往往发生得太早,导致它们与主要内容的图片争夺带宽。

尽管 Chrome 将预加载请求标记为最低优先级,但我们网站上优先级最高的 Largest Contentful Paint(LCP)图片仍然没有被快速下载。

小贴士理论上,服务器也应该识别资源的优先级,并优先发送重要资源。但在实际情况中,许多云服务提供商并未正确支持这一功能。

这对真实用户有影响吗?

实验室环境下的性能测试是在模拟条件下进行的,往往与真实用户的体验不完全一致。例如,大多数访客的网络连接速度快于 Google Lighthouse 测试时所使用的带宽。

因此,我们搭建了真实用户监测(Real User Monitoring,RUM),跟踪主要图片的加载时间和第一个预加载的 JavaScript 文件的完成时间。结果发现,在大多数情况下,预加载的 JavaScript 竟然比关键图片先加载完成!

ℹ️ 需要注意的点无论优先级如何,预加载的 JavaScript 仍然有一定优势,因为它来自与 HTML 文档相同的域,而图片则需要建立新的服务器连接。

关闭预加载后,性能是否有所提升?

那么,预加载文件过早加载是否影响了用户看到页面内容的时间?为了测试这一点,我们让预加载链接标签仅在一半的情况下生效,并对比其影响。

最终,我们并未观察到明显的差异,不过 75% 分位数的 LCP(Largest Contentful Paint)得分在禁用预加载时快了 100 毫秒。

真实用户的 TTFB(首字节时间)对比

在 90% 分位数时,测试结果基本相同;但在 95% 分位数时,开启 JavaScript 预加载的页面反而更快♂️。

预加载资源过早加载是常见现象吗?

在寻找使用预加载的网站时,我们发现很难找到真正等到网络空闲才进行预加载的网站。

理想情况下,浏览器应该在主页面内容渲染完成后才开始预加载资源。然而,实际情况往往并非如此。下面的示例显示,即使是最低优先级的 JavaScript 也会被提前加载。

请求瀑布图显示了预加载资源过早加载的情况

当然,这并不一定意味着 LCP(Largest Contentful Paint)会被延迟。页面加载过程中会涉及许多资源请求和处理,适量使用带宽进行预加载未必是坏事。但即便如此,在页面打开不到 1 秒的时间内,预加载文件就开始下载,仍然显得不太合理!

ℹ️ 需要注意的点在测试中,我们还发现某个网站在 LCP 发生之前,就已经预加载了超过 1MB 的内容。不过,这些资源由多个 10KB 左右的小图片组成,因此在请求瀑布图中很难截图展示。

如何防止预加载影响网站性能?

为了避免预加载资源与关键内容争夺带宽,不要直接在初始 HTML 页面或 HTTP 头中添加预加载提示(prefetch hints)。

正确做法:使用 JavaScript 在页面加载完成后再动态插入预加载标签。例如:

window.addEventListener("load",()=>{ const link = document.createElement("link"); link.as ="style"; link.rel ="prefetch"; link.href ="page-3.css"; document.head.appendChild(link);});结论

预加载资源往往会过早加载,可能会与页面渲染所需的关键资源争夺带宽。然而,在很多情况下,页面性能并不会受到带宽的限制,因此预加载对页面速度的影响可能并不明显。

Chrome 仍有优化空间,比如等到页面完全加载后再触发预加载。在 Firefox 的测试中,我们发现它的预加载机制更为合理 —— 预加载请求会被延迟更长时间,从而确保主要页面内容优先渲染。

0 阅读:5
程序员咋不秃头

程序员咋不秃头

感谢大家的关注