前端性能 - 关于资源预加载（Resource Hints）

从 HTML Standard 可以看到，Link Types 所拥有的类型，在日常中关注性能优化的应该也会使用过过 dns-prefetch / preconnect / prefetch / preload 等资源预加载的技术。

那么，它们之前都有什么样的区别，如果正确使用才能提高页面的性能呢？

首先，对于一个资源的请求来说，大致经过的阶段如下：

Copy


--- title: Network --- flowchart LR A(DNS):::c1 -.->B(TCP):::c2-.->C(TLS):::c3--> D(Request):::c4--> E(Response):::c5 classDef c1 stroke:#ddad5c classDef c2 stroke:#b12d70 classDef c3 stroke:#aaf196 classDef c4 stroke:#2ef5f3 classDef c5 stroke:#fafb7e

dns-prefetch

Copy


--- title: dns-prefetch --- flowchart LR subgraph dns cache A(DNS) end A(DNS):::c1-.->B(TCP):::c2-.->C(TLS):::c3--> D(Request):::c4--> E(Response):::c5 classDef c1 stroke:#ddad5c classDef c2 stroke:#b12d70 classDef c3 stroke:#aaf196 classDef c4 stroke:#2ef5f3 classDef c5 stroke:#fafb7e

preconnect

Copy


--- title: preconnect --- flowchart LR subgraph preconnect cache A(DNS) B(TCP) C(TLS) end A:::c1-.->B:::c2-.->C:::c3--> D(Request):::c4--> E(Response):::c5 classDef c1 stroke:#ddad5c classDef c2 stroke:#b12d70 classDef c3 stroke:#aaf196 classDef c4 stroke:#2ef5f3 classDef c5 stroke:#fafb7e

prefetch

Copy


从名字可以看出来，就是预先缓存资源，然后当需要使用到这个资源的时候，直接从浏览器的缓存中取出，从而提高用户体验。

prefetch 的加载策略有两种类型：

预测性预加载（Predictive Prefetching）：浏览器根据用户的行为和历史数据来预测将来可能会访问的页面，并在后台预加载相关资源。这种策略可以在用户实际点击链接之前提前加载资源，以减少页面加载时间。

提前预加载（Eager Prefetching）：在 HTML 中显式地指定需要预加载的资源。这些资源可能是当前页面所需的资源，也可以是其他页面的资源。通过提前加载这些资源，可以减少后续页面的加载时间。

现在讨论的是第 2 种情况。

要注意的是，浏览器并不一定会执行 prefetch。虽然 prefetch 是一种建议性的加载策略，但具体是否执行预加载取决于浏览器的实现和策略。

浏览器在解析 HTML 页面时会检测 prefetch 标签，并根据自身的策略来决定是否执行预加载。浏览器可能会考虑多个因素，包括当前网络连接的状况、系统资源的使用情况、用户行为等。如果浏览器认为执行预加载会对用户体验产生积极影响，它可能会选择执行预加载，否则可能会忽略 prefetch 标签。

因此，我们不能完全依赖浏览器执行 prefetch，而应该将 prefetch 视为一种优化手段，用于提高用户体验。同时，还应该注意合理使用 prefetch，避免过度预加载导致不必要的网络流量和资源浪费。

preload

Copy


preload 是一种强制性的加载策略，与 prefetch 不同，浏览器会立即执行预加载操作。

preload 的加载策略有两种情况：

提前预加载（Eager Preloading）：在 HTML 中使用 标签来指定需要预加载的资源。这些资源可以是当前页面所需的资源，也可以是其他页面的资源。通过提前加载这些资源，可以减少后续页面的加载时间。

隐式预加载（Implicit Preloading）：浏览器根据页面的 HTML、CSS 和 JavaScript 代码中的引用关系来自动判断需要预加载的资源。例如，当浏览器解析 HTML 页面时，发现某个图片元素被 JavaScript 动态创建并插入到页面中，浏览器可能会自动预加载该图片资源。

要注意是，preload 是一种强制性的加载策略，浏览器会立即执行预加载操作，无论当前网络连接的状况如何。这可以确保在页面加载时，一些关键资源已经被提前加载，并且在后续的渲染过程中可以立即使用。

与 prefetch 类似，我们在使用 preload 时需要谨慎评估预加载的资源和对网络带宽的消耗，以及对用户体验的实际影响。

举个例子，如果用户的网络带宽不高，或者设备性能比较落后，那么大量的 preload 资源将会极大的影响用户使用体验。

--EOF--

Resource Hints (W3C)