在Next.js中使用动态导入进行代码拆分
如何通过代码拆分和智能加载策略来加速Next.js应用程序。
基于路由和基于组件的代码分裂
默认情况下,Next.js将您的JavaScript分成每个路由的独立块。当用户加载您的应用程序时,Next.js仅发送初始路由所需的代码。当用户在应用程序中导航时,他们获取与其他路由关联的块。基于路由的代码拆分可最大程度地减少需要立即解析和编译的脚本的数量,从而缩短页面加载时间。
虽然基于路由的代码拆分是一个很好的默认设置,但是您可以通过在组件级别进行代码拆分来进一步优化加载过程。如果您的应用程序中包含大型组件,则最好将它们分成单独的块。这样,任何不重要的或仅在某些用户交互(例如单击按钮)上呈现的大型组件都可以延迟加载。
Next.js支持dynamicimport()
,它允许您动态导入JavaScript模块(包括React组件)并将每个导入加载为单独的块。这使您可以拆分组件级代码,并使您能够控制资源加载,以便用户仅下载他们正在查看的网站部分所需的代码。在Next.js中, 默认情况下这些组件是服务器端呈现(SSR)。
在行动动态进口
这篇文章包括一个示例应用程序的多个版本,其中包括一个带有一个按钮的简单页面。单击按钮时,您会看到一只可爱的小狗。在浏览该应用程序的每个版本时,您将看到动态导入与静态导入 有何不同以及如何使用它们。
在该应用的第一个版本中,幼犬居住在components/Puppy.js
。要在页面上显示小狗,应用程序会使用静态import语句导入Puppy
组件 index.js
:
import Puppy from "../components/Puppy";
要查看Next.js如何捆绑该应用程序,请检查DevTools中的网络跟踪:
-
要预览站点,请按View App。然后按 全屏 。
-
按
Control+Shift+J
(或Command+Option+J
在Mac上)按打开DevTools。 -
单击网络选项卡。
-
选择禁用缓存复选框。
-
重新加载页面。
加载页面时,所有必需的代码(包括Puppy.js
组件)都捆绑在index.js
:
当您单击“单击我”按钮时,仅将对JPEG小狗的请求添加到“网络”选项卡中:
这种方法的缺点是,即使用户没有单击按钮来查看小狗,他们也必须加载该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
下载。这次它减小了0.5 KB(从37.9 KB减少到37.4 KB),因为它不包含该Puppy
组件的代码:
Puppy
现在,该组件位于一个单独的块中1.js
,该块仅在您按下按钮时才加载:
默认情况下,Next.js将这些动态块命名为数字.js,其中 数字从1开始。
在实际的应用程序中,组件通常要大得多,并且延迟加载它们可以将您的初始JavaScript有效负载减少数百千字节。
进口动态自定义负载指示灯
延迟加载资源时,最好提供一个加载指示器,以防出现任何延迟。在Next.js中,您可以通过为dynamic()
函数提供一个附加参数来做到这一点:
const Puppy = dynamic(() => import("../components/Puppy"), {
loading: () => <p>Loading...</p>
});
要查看正在运行的加载指示器,请在DevTools中模拟缓慢的网络连接:
-
要预览站点,请按View App。然后按 全屏 。
-
按
Control+Shift+J
(或Command+Option+J
在Mac上)按打开DevTools。 -
单击网络选项卡。
-
选择禁用缓存复选框。
-
在“限制”下拉列表中,选择“快速3G”。
-
按下[点击我]按钮。
现在,当您单击按钮时,将花费一些时间来加载组件,同时应用程序会显示“正在加载...”消息。
动态无进口SSR
如果只需要在客户端上渲染组件(例如,聊天小部件),则可以通过将ssr
选项设置为来实现false
:
const Puppy = dynamic(() => import("../components/Puppy"), {
ssr: false,
});
结论
借助对动态导入的支持,Next.js为您提供了组件级代码拆分,这可以最大程度地减少JavaScript负载并缩短应用程序加载时间。默认情况下,所有组件都是在服务器端呈现的,您可以在必要时禁用此选项。
原文地址:https://web.dev/code-splitting-with-dynamic-imports-in-nextjs/