在 Next.js 中使用动态导入功能进行代码拆分

如何利用代码拆分和智能加载策略提升 Next.js 应用的运行速度。

Milica Mihajlija
Milica Mihajlija

您将学到什么?

此博文介绍了不同类型的代码 拆分以及如何使用 来提升 Next.js 应用的运行速度。

基于路由和基于组件的代码拆分

默认情况下,Next.js 会针对每条路线将 JavaScript 拆分成多个单独的块。 当用户加载您的应用时,Next.js 只会发送 。当用户在应用中导航时,他们会提取数据块 与其他路由相关联基于路由的代码拆分可最大限度地减少 同时需要进行解析和编译的脚本数量, 缩短网页加载时间。

虽然基于路由的代码拆分是很好的默认设置,但您还可以进一步优化 在组件级别进行代码拆分。如果您的集群 组件,最好将它们拆分成多个独立的部分。 这样,任何不重要的或仅在特定环境下呈现的大型组件 可以对用户互动(如点击按钮)进行延迟加载。

Next.js 支持动态 import(), 它允许您导入 JavaScript 模块(包括 React 组件) 并且将每次导入作为单独的分块进行加载这样您就可以 组件级代码拆分,可让您控制资源加载, 确保用户只下载他们需要的代码 他们正在观看的内容在 Next.js 中,这些组件在服务器端呈现 (SSR) 默认情况。

动态导入的实际应用

这篇博文包含示例应用的多个版本,其中包含一个简单的 只需一个按钮。点击该按钮后,您会看到一只可爱的小狗。如 浏览应用的各个版本时,会发现动态导入 不同于静态 导入 以及如何与它们合作

在应用的第一个版本中,小狗住在 components/Puppy.js 中。接收者 在页面上显示 Puppy 组件, 将 index.js 替换为静态 import 语句:

import Puppy from "../components/Puppy";

如需了解 Next.js 如何捆绑应用,请在开发者工具中检查网络跟踪记录:

  1. 如需预览网站,请按查看应用。然后按 全屏 全屏

  2. 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。

  3. 点击网络标签页。

  4. 选中停用缓存复选框。

  5. 重新加载页面。

加载页面时,所有必需的代码(包括 Puppy.js) 组件捆绑在 index.js 中:

开发者工具的“Network”标签页,显示了以下 6 个 JavaScript 文件:index.js、app.js、webpack.js、main.js、0.js 和 dll(动态链接库)文件。

当您按 Click me 按钮时,只有请求小狗 JPEG 添加到网络标签页中:

点击按钮后开发者工具的“Network”标签页,显示了相同的 6 个 JavaScript 文件和 1 个图片。

这种方法的缺点是,即使用户不点击该按钮 看到小狗,他们必须加载 Puppy 组件,因为它包含在 index.js。这个小例子没什么大不了,但在现实世界中 通常,只有当应用加载大组件时, 。

现在,请查看应用的第二个版本,其中静态导入是 已替换为动态导入Next.js 包含 next/dynamic,因此 为 Next 中的任何组件使用动态导入:

import Puppy from "../components/Puppy";
import dynamic from "next/dynamic";

// ...

const Puppy = dynamic(import("../components/Puppy"));

按照第一个示例中的步骤检查网络跟踪记录。

首次加载应用时,系统只会下载 index.js。这次是 由于 不包含 Puppy 组件的代码:

显示相同的 6 个 JavaScript 文件的开发者工具网络,但 index.js 现在缩小了 0.5 KB。

Puppy 组件现在位于单独的块 1.js 中,该块仅加载 按钮:

<ph type="x-smartling-placeholder">
</ph> 点击按钮后的 DevTools 的 Network 标签页,显示额外的 1.js 文件和添加到文件列表底部的图片。

在实际应用中,组件通常会 更大,以及延迟加载 可以将初始 JavaScript 载荷减少数百 KB

带有自定义加载指示器的动态导入

延迟加载资源时,最好提供加载指示器 以免发生延迟情况在 Next.js 中,您可以通过提供一个 dynamic() 函数的一个附加参数:

const Puppy = dynamic(() => import("../components/Puppy"), {
  loading: () => <p>Loading...</p>
});

要查看加载指示器的实际效果,请在以下应用中模拟慢速网络连接: 开发者工具:

  1. 如需预览网站,请按查看应用。然后按 全屏 全屏

  2. 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。

  3. 点击网络标签页。

  4. 选中停用缓存复选框。

  5. Throttling 下拉列表中,选择 Fast 3G

  6. 点击此处按钮。

现在,当您点击该按钮时,需要一段时间才能加载组件和应用 会显示“正在加载...”消息。

显示文本的深色屏幕

不使用 SSR 的动态导入

如果您只需要在客户端呈现组件(例如,聊天窗口), 微件),可以通过将 ssr 选项设置为 false 来实现此目的:

const Puppy = dynamic(() => import("../components/Puppy"), {
  ssr: false,
});

总结

Next.js 支持动态导入,可为您提供组件级代码 从而最大程度地减少 JavaScript 负载 加载时间。默认情况下,所有组件均在服务器端呈现,您可以 必要时停用此选项。