Skip to content

好的,我们来详细梳理一下前端中的 preloadprefetch。它们是两种非常重要的资源提示(Resource Hints),用于优化页面加载性能和用户体验,但目的和应用场景有显著区别。

核心概念就一句话:

  • Preload:加载当前页面必定需要的资源。(高优先级,当前用)
  • Prefetch:加载未来页面可能需要的资源。(低优先级,未来用)

下面我们分别详细解释。


1. Preload

preload 的核心思想是 “提前加载,即刻使用”。它告诉浏览器,当前页面非常需要某个资源,请以高优先级尽快获取它。浏览器会为此资源分配高优先级,但不会执行它(比如脚本不会执行,样式表不会应用),只是提前缓存到本地。当页面真正需要用到该资源时,它已经在缓存里了,可以直接从磁盘读取,从而消除了网络请求的延迟。

如何使用

主要通过 `` 标签的 rel="preload" 属性,并配合 as 属性来指定资源类型。

html
<link rel="preload" href="critical-font.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="hero-image.jpg" as="image">
<link rel="preload" href="main.js" as="script">
<link rel="preload" href="theme.css" as="style">

关键特性与使用场景

  • 高优先级:浏览器会以较高的优先级(High)来获取这些资源。
  • 必须指定 as 属性:这非常重要。它告诉浏览器资源类型,以便:
    1. 设置正确的请求优先级。
    2. 应用正确的内容安全策略(CSP)。
    3. 浏览器能判断资源是否在缓存中已存在,避免重复请求。
  • 用于关键资源:非常适合用于渲染首屏内容所必需的关键资源,例如:
    • 首屏的大型图片或 Web字体。
    • 关键的CSS或JS文件。
    • 首屏视频 poster 图。
  • 浏览器支持:现代浏览器普遍支持。

最佳实践示例

一个典型场景是预加载Web字体。字体文件通常藏在CSS中,浏览器要很晚才能发现并请求,容易导致文字样式闪烁(FOIT/FOUT)。使用 preload 可以强制浏览器提前请求字体。

html
<!-- 提前请求字体,即使CSS还没解析到 -->
<link rel="preload" href="myfont.woff2" as="font" type="font/woff2" crossorigin>

<!-- 正常的CSS引用 -->
<link rel="stylesheet" href="styles.css">

styles.css 中定义了 @font-face { font-family: 'MyFont'; src: url(myfont.woff2) format('woff2'); }。这样字体请求会和CSS请求几乎同时发出,大大减少了字体加载带来的布局偏移和样式闪烁。


2. Prefetch

prefetch 的核心思想是 “闲时加载,未来使用”。它告诉浏览器,这个资源用户可能在未来的导航中会用到(比如下一个页面)。浏览器会在空闲时间(idle time)以最低优先级(Lowest)获取并缓存这个资源。当用户真正访问下一个页面时,如果该页面需要这个资源,它已经被缓存了,可以立即使用,从而大幅提升下一个页面的加载速度。

如何使用

同样使用 `` 标签,但 rel="prefetch"

html
<link rel="prefetch" href="next-page.js">
<link rel="prefetch" href="next-page.css">
<link rel="prefetch" href="avatar.png">

关键特性与使用场景

  • 低优先级:浏览器只在带宽空闲时才会加载它,绝不会影响当前页面的关键资源加载。
  • 用于未来导航:主要用于优化用户下一步可能去往的页面的体验。例如:
    • 在电商首页,预取用户最可能点击的“热门商品”详情页的资源。
    • 在长文章的第一页,预取第二页的资源。
    • 预取用户鼠标悬停的链接资源(结合一些简单的JavaScript预测)。
  • 缓存时间: prefetch 的资源会被缓存一段时间(取决于浏览器,通常5分钟左右),供后续页面使用。
  • DNS Prefetch:还有一个相关的 dns-prefetch,只专门用于提前进行DNS解析,适用于跨域域名,开销极小。
    html
    <link rel="dns-prefetch" href="https://api.example.com">

对比总结表

特性PreloadPrefetch
核心目的提前加载当前页面关键资源提前加载未来页面可能需要的资源
加载时机立即,以高优先级获取空闲时,以低优先级获取
优先级 (High)非常低 (Lowest)
浏览器缓存缓存到磁盘,供当前页面使用缓存到磁盘(或HTTP缓存),供未来页面使用
使用场景字体、首屏大图、关键CSS/JS下一个页面的脚本、样式、图片等
语法示例<link rel="preload" href="a.js" as="script"><link rel="prefetch" href="b.js">

常见误区与注意事项

  1. 不要滥用 Preload:如果对非关键资源使用 preload,会挤占网络带宽,反而损害当前页面的性能,因为它会以高优先级抢夺关键资源(如自身JS/CSS)的下载时间。只预加载真正关键的资源。
  2. Preload 和 Prefetch 都会请求资源:它们都会真实地发起HTTP请求。如果资源在缓存中已存在(例如通过Service Worker缓存),浏览器可能不会再次请求。
  3. Prefetch 是一种预测:它基于你对用户行为的预测。如果预测错误,用户根本没有访问下一个页面,那么这次预取就是一种带宽浪费。
  4. 双请求问题:如果你预取了一个资源(如 script.js),而下一个页面也确实引用了它,大部分现代浏览器会从缓存中读取,而不会发起第二次请求。但某些老旧浏览器或特殊场景下可能仍会验证缓存,需要注意。

总结

选择 preload 还是 prefetch,完全取决于你的目标:

  • 让当前页面加载更快?找出渲染阻塞的关键资源,使用 preload
  • 让用户下一个页面的体验如丝般顺滑?预测用户行为,使用 prefetch

正确使用这两种资源提示,可以显著提升网站的性能感知和用户体验。