通过预测性预提取提高网页导航速度

了解预测性预提取以及 Guess.js 如何实现预测性预提取。

在 2019 年 Google I/O 大会上,我在利用预测性预提取加快 Web 导航速度会议中首先介绍了如何使用代码分块优化 Web 应用,以及对后续网页导航的潜在性能影响。在演讲的第二部分,我介绍了如何使用 Guess.js 设置预测性预提取来提高导航速度:

代码分块,加快 Web 应用的运行速度

Web 应用运行缓慢,JavaScript 是您分发的资源中最昂贵的资源之一。等待加载速度缓慢的 Web 应用可能会让用户感到沮丧,并降低转化率。

运行缓慢的 Web 应用会让人感到压力。

延迟加载是一种有效的技术,可减少通过网络传输的 JavaScript 字节数。您可以使用多种方法延迟加载 JavaScript,包括:

  • 组件级代码拆分
  • 路径级代码拆分

借助组件级代码拆分,您可以将各个组件移至单独的 JavaScript 分块中。在特定事件中,您可以加载相关脚本并渲染组件。

不过,使用路由级代码拆分时,您可以将整个路由移至独立的代码块中。当用户从一个路由转换到另一个路由时,他们必须下载关联的 JavaScript 并引导所请求的网页。这些操作可能会导致严重延迟,尤其是在网络速度较慢的情况下。

预提取 JavaScript

借助预提取功能,浏览器可以下载并缓存用户可能很快就需要的资源。常用的方法是使用 <link rel="prefetch">,但存在两个常见的陷阱:

  • 预提取资源过多(过度提取)会消耗大量数据。
  • 用户需要的某些资源可能永远不会预提取。

预测性预提取通过使用用户导航模式报告来确定要预提取的资源,从而解决这些问题。

预提取示例

使用 Guess.js 进行预测性预加载

Guess.js 是一个 JavaScript 库,提供预测性预提取功能。Guess.js 会使用 Google Analytics 或其他分析服务提供商提供的报告来构建预测模型,以便智能地预加载用户可能需要的内容。

Guess.js 已与 AngularNext.jsNuxt.jsGatsby 集成。如需在应用中使用该代码,请将以下代码行添加到 webpack 配置中,以指定 Google Analytics 视图 ID

const { GuessPlugin } = require('guess-webpack');

// ...
plugins: [
   // ...
   new GuessPlugin({ GA: 'XXXXXX' })
]
// ...

如果您不使用 Google Analytics,则可以指定 reportProvider,并从您喜爱的服务中下载数据。

与框架集成

如需详细了解如何将 Guess.js 与您喜爱的框架集成,请参阅以下资源:

如需快速了解与 Angular 的集成,请观看以下视频:

Guess.js 如何运作?

下面是 Guess.js 实现预测性预提取的方式:

  1. 它首先会从您偏好的分析服务提供商那里提取用户导航模式的数据。
  2. 然后,它会将报告中的网址映射到 webpack 生成的 JavaScript 分块。
  3. 它会根据提取的数据创建一个简单的预测模型,以预测用户从任何给定网页跳转到的网页。
  4. 它会针对每个 JavaScript 分块调用模型,预测接下来可能需要的其他分块。
  5. 它会向每个分块添加预取指令。

Guess.js 完成后,每个分块都将包含类似以下内容的预加载指令:

__GUESS__.p(
  ['a.js', 0.2],
  ['b.js', 0.8]
)

这段由 Guess.js 生成的代码会告知浏览器考虑以概率 0.2 预提取分块 a.js,并以概率 0.8 预提取分块 b.js

浏览器执行代码后,Guess.js 会检查用户的连接速度。如果足够,Guess.js 会在网页的标头中插入两个 <link rel="prefetch"> 标记,每个分块一个。如果用户使用的是高速网络,Guess.js 会预加载这两个分块。如果用户的网络连接不佳,Guess.js 只会预加载分块 b.js,因为该分块很有可能被需要。

了解详情

如需详细了解 Guess.js,请参阅以下资源: