【总结】2326- 资源预加载可能会拖慢网站速度

less 复制代码
译者:@飘飘 

作者:@Matt Zeunert 

原文: https://www.debugbear.com/blog/prefetch-slower-website

前言

探讨了资源预取(prefetching)可能导致网站加载速度变慢的问题,并提供了解决方案。今日文章 @Matt Zeunert 分享,@前端早读课飘飘翻译。

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

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

资源预加载的作用

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

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

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

ini 复制代码
<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 在页面加载完成后再动态插入预加载标签。例如:

ini 复制代码
 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 的测试中,我们发现它的预加载机制更为合理 ------ 预加载请求会被延迟更长时间,从而确保主要页面内容优先渲染。

相关推荐
程序猿阿伟1 小时前
《首屏加载优化手册:Vue3+Element Plus项目提速的技术细节》
前端·javascript·vue.js
麦麦大数据2 小时前
D030知识图谱科研文献论文推荐系统vue+django+Neo4j的知识图谱|论文本文相似度推荐|协同过滤
vue.js·爬虫·django·知识图谱·科研·论文文献·相似度推荐
尘觉2 小时前
面试-浅复制和深复制?怎样实现深复制详细解答
javascript·面试·职场和发展
fruge3 小时前
Vue Pinia 状态管理实战指南
前端·vue.js·ubuntu
绝无仅有3 小时前
某教育大厂面试题解析:MySQL索引、Redis缓存、Dubbo负载均衡等
vue.js·后端·面试
sean3 小时前
开发一个自己的 claude code
前端·后端·ai编程
用户21411832636023 小时前
dify案例分享-用 Dify 一键生成教学动画 HTML!AI 助力,3 分钟搞定专业级课件
前端
chxii4 小时前
ISO 8601日期时间标准及其在JavaScript、SQLite与MySQL中的应用解析
开发语言·javascript·数据库
没逛够4 小时前
Vue 自适应高度表格
javascript·vue.js·elementui
太过平凡的小蚂蚁5 小时前
Kotlin 协程中常见的异步返回与控制方式(速览)
开发语言·前端·kotlin