Skip to content

延迟加载

¥Lazy Loading

Next.js 中的 延迟加载 通过减少渲染路由所需的 JavaScript 数量来帮助提高应用的初始加载性能。

¥Lazy loading in Next.js helps improve the initial loading performance of an application by decreasing the amount of JavaScript needed to render a route.

它允许你推迟加载客户端组件和导入的库,并且仅在需要时将它们包含在客户端包中。例如,你可能希望推迟加载模式,直到用户单击将其打开。

¥It allows you to defer loading of Client Components and imported libraries, and only include them in the client bundle when they're needed. For example, you might want to defer loading a modal until a user clicks to open it.

在 Next.js 中可以通过两种方式实现延迟加载:

¥There are two ways you can implement lazy loading in Next.js:

  1. 动态导入next/dynamic 一起使用

    ¥Using Dynamic Imports with next/dynamic

  2. React.lazy()悬念 一起使用

    ¥Using React.lazy() with Suspense

默认情况下,服务器组件自动为 代码分割,你可以使用 streaming 逐步将 UI 片段从服务器发送到客户端。延迟加载适用于客户端组件。

¥By default, Server Components are automatically code split, and you can use streaming to progressively send pieces of UI from the server to the client. Lazy loading applies to Client Components.

next/dynamic

next/dynamicReact.lazy()悬念 的复合体。它在 apppages 目录中的行为方式相同,以允许增量迁移。

¥next/dynamic is a composite of React.lazy() and Suspense. It behaves the same way in the app and pages directories to allow for incremental migration.

示例

¥Examples

使用 next/dynamic 后,header 组件将不会包含在页面的初始 JavaScript 包中。页面将首先渲染 Suspense fallback,然后在解析 Suspense 边界后渲染 Header 组件。

¥By using next/dynamic, the header component will not be included in the page's initial JavaScript bundle. The page will render the Suspense fallback first, followed by the Header component when the Suspense boundary is resolved.

需要了解:在 import('path/to/component') 中,必须明确指定路径。它不能是模板字符串或变量。此外,import() 必须位于 dynamic() 调用中,以便 Next.js 能够将 webpack 包/模块 ID 与特定的 dynamic() 调用匹配,并在渲染之前预加载它们。dynamic() 不能在 React 渲染中使用,因为它需要在模块顶层进行标记才能实现预加载,类似于 React.lazy

¥Good to know: In import('path/to/component'), the path must be explicitly written. It can't be a template string nor a variable. Furthermore the import() has to be inside the dynamic() call for Next.js to be able to match webpack bundles / module ids to the specific dynamic() call and preload them before rendering. dynamic() can't be used inside of React rendering as it needs to be marked in the top level of the module for preloading to work, similar to React.lazy.

使用命名导出

¥With named exports

要动态导入命名导出,你可以从 import() 返回的 Promise 中返回它:

¥To dynamically import a named export, you can return it from the Promise returned by import():

不使用 SSR

¥With no SSR

要在客户端动态加载组件,你可以使用 ssr 选项禁用服务器渲染。如果外部依赖或组件依赖于像 window 这样的浏览器 API,这将非常有用。

¥To dynamically load a component on the client side, you can use the ssr option to disable server-rendering. This is useful if an external dependency or component relies on browser APIs like window.

使用外部库

¥With external libraries

本例使用外部库 fuse.js 进行模糊搜索。该模块仅在用户输入搜索内容后才会在浏览器中加载。

¥This example uses the external library fuse.js for fuzzy search. The module is only loaded in the browser after the user types in the search input.