通过代码拆分减少 JavaScript 载荷

没人喜欢等待。 如果网站的加载时间超过 3 秒,超过 50% 的用户会放弃该网站

发送大量 JavaScript 载荷会影响网站的速度 显著增加。不要将所有 JavaScript 都交付给用户 加载应用的第一个页面时,请将 bundle 拆分为 多份内容,并且在一开始就只发送必要的信息。

为什么代码拆分有利?

代码拆分是一种旨在最大限度地缩短启动时间的技术。当我们在启动时发布的 JavaScript 减少时,我们可以尽量减少这个关键阶段的主线程工作,从而提高应用的交互速度

对于核心网页指标,减少启动时下载的 JavaScript 载荷将有助于缩短下一次绘制的互动 (INP) 时间。其原因在于,通过释放主线程,应用可通过降低与 JavaScript 解析、编译和执行相关的启动成本来更快地响应用户输入。

根据您网站的架构(尤其是您的网站高度依赖客户端呈现的情况),减少负责呈现标记的 JavaScript 载荷的大小有助于改进 Largest Contentful Paint (LCP)。如果 LCP 资源延迟到客户端标记完成才被浏览器发现,或者主线程太忙而无法呈现该 LCP 元素,就可能会发生这种情况。这两种情况都会延迟网页的 LCP 时间。

测量

当花费大量时间时,Lighthouse 会显示失败的审核 在页面上执行所有 JavaScript

失败的 Lighthouse 审核显示脚本的执行时间过长。

拆分 JavaScript 软件包,以便仅在调用 用户加载应用这样可以尽可能减少 经过解析和编译,从而缩短网页加载时间。

热门模块打包器,例如 webpackParcel 和 利用总览功能, 和动态导入捆绑包。 例如,请考虑以下代码段,该代码段显示了 提交表单时触发的 someFunction 方法。

import moduleA from "library";

form.addEventListener("submit", e => {
  e.preventDefault();
  someFunction();
});

const someFunction = () => {
  // uses moduleA
}

在这里,someFunction 使用从特定库导入的模块。如果 此模块未用于其他地方,那么您可以修改此代码块以使用 动态导入,以便仅在用户提交表单时提取该数据。

form.addEventListener("submit", e => {
  e.preventDefault();
  import('library.moduleA')
    .then(module => module.default) // using the default export
    .then(() => someFunction())
    .catch(handleError());
});

const someFunction = () => {
    // uses moduleA
}

构成模块的代码不会添加到初始 bundle 中 现在会延迟加载,或者只在需要后才提供给用户 表单提交。如需进一步提高网页性能,请预加载关键分块,以便优先处理并尽快提取它们

虽然前面的代码段是一个简单的示例, 依赖项不是大型应用中的常见模式。通常 方依赖项会拆分成可以缓存的单独供应商软件包 因为它们的更新频率较低如需详细了解 SplitChunksPlugin 可以 可以帮助您实现这一目标。

使用客户端框架时,在路线或组件级别进行拆分是 一种更简单的方法,用于延迟加载应用的不同部分。很多 使用 webpack 的流行框架提供抽象来实现延迟加载 这比自行研究配置要简单得多