延迟加载
¥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:
将 动态导入 与
next/dynamic
一起使用¥Using Dynamic Imports with
next/dynamic
将
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/dynamic
是 React.lazy()
和 悬念 的复合体。它在 app
和 pages
目录中的行为方式相同,以允许增量迁移。
¥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 theimport()
has to be inside thedynamic()
call for Next.js to be able to match webpack bundles / module ids to the specificdynamic()
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 toReact.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.