next/dynamic
是 NextJS 中的一个模块,它是 React 的 React.lazy()
以及 Suspense
的组合,用与动态/按需加载模块,这样在初次加载页面时,这些模块不会被加载,只有在真正需要的时候才会被加载,也就是所谓的代码拆分(code splitting)或懒加载(lazy loading) - Optimizing: Lazy Loading | Next.js
什么时候使用next/dynamic
,考虑因素是什么?
- 大型的组件或库(图表库、富文本等:如果有一个非常大的组件或库,只在特定的条件下才会展示,使用
next/dynamic
可以帮助减少初始页面的大小和加载时间 - 不常用的组件(弹窗、侧边栏、Tab:如果某些组件只在特定的用户交互之后才展示,可以使用
next/dynamic
来动态加载他们 - 第三方库与服务器渲染的不兼容:有些第三方库可能依赖于
window
或其他浏览器特定的API。在这种情况下,可以使用next/dynamic
并设置{ssr: false}
来确保这些库只在客户端被加载和执行。
判断是否要使用 next/dynamic
:
- 性能分析:使用 NextJS 提供的内置性能分析工具或其他工具(Webpack Bundle Analyzer) 来检查哪些库或者模块增加了项目的
bundle
大小。 - 用户交互:思考用户的常规路径和交互。如果某个功能或组件只在特定交互后使用,那么可能它是一个动态加载的好候选
- 服务器渲染问题:在开发工程中,如果遇到了与服务器渲染相关的问题,例如(
window is not defined
错误,这可能是一个提示,告诉你可以考虑使用next/dynamic
。
next/dynamic
是一个强大的工具,但并不是每个组件都需要它,在决定使用之前,应该先评估其潜在的性能影响和用户体验的提升
与 React.lazy 的区别
使用 next/dynamic
与 React.lazy
看起来是等效的,但也有一些区别
- 服务端渲染或SSR 只能通过
next/dynamic
实现,而不能通过React.lazy
实现 - 每个React 组件都有一个
typeof
,它是由React中的 Symbol 函数定义的,next/dynamic
typeof 是React
前向引用,而在 React.lazy 中是react.lazy
next/dynamic
可以允许React
组件的命名导出和默认导出,而React.lazy
只允许默认导出
![TIP] dynamic 只适合在客户端组件使用,而不适合在服务端组件中使用,不然依然后会在未使用的情况下发送到浏览器客户端 → Reddit 如果您在服务器组件内执行 lazy 或 next/dynamic,它们实际上不会进行代码拆分。您需要先将其延迟导入到另一个标有 use client 的组件中,然后将其导入服务器组件。