introduction

Next.js 支持懒加载外部库(通过import())以及 React组件中通过next/dynamic懒加载库 …

延迟加载能够帮助提高初始加载性能(通过减少渲染这个页面的必要的js的体积) …

仅仅当他们被使用的时候才会导入并包括在js 打包中 ..

next/dynamic是一个React.lazy扩展,当与Suspense合并使用的时候,组件能够延迟水和直到暂停边界被解析了 …

Example

通过使用next/dynamic,这个header 组件将不会包括在页面的初始 js 打包中,这个页面将会首先会渲染一个可暂停的fallback,当Suspense边界解析完毕之后才显示 Header组件 …

注意:

当在import(/path/to/component')时,路径必须显式的写入,它不能是模板字符串或者变量,因此对于next.js中的 dynamic()内部的import()调用能够匹配webpack 资源或者模块id 到特定的 dynamic()调用并且在渲染它们之前进行预加载 .. dynamic()不能够使用在React 渲染内部(因为它需要在模块的顶级部分进行标识为了预加载能够工作),类似于React.lazy

如果你没有使用React 18,你能够使用loading属性替代Suspense的fallback

  1. const DynamicHeader = dynamic(() => import('../components/header'), {
  2. loading: () => <header />,
  3. })

也就是说React 17 或许没有fallback …

具名暴露

为了动态导入一个命名暴露,你能够通过import()返回的Promise 中返回它 …

  1. // components/hello.js
  2. export function Hello() {
  3. return <p>Hello!</p>
  4. }
  5. // pages/index.js
  6. import dynamic from 'next/dynamic'
  7. const DynamicComponent = dynamic(() =>
  8. import('../components/hello').then((mod) => mod.Hello)
  9. )

With no SSR

为了加载客户端动态的加载一个组件,你能够使用ssr选项去禁用服务端渲染,这有一种好处(如果外部依赖或者组件依赖于浏览器的API(例如于window)

  1. import dynamic from 'next/dynamic'
  2. const DynamicHeader = dynamic(() => import('../components/header'), {
  3. ssr: false,
  4. })

With external libraries

举个例子,当使用外部库fuse.js进行 模糊查询. 这个模块仅仅在浏览器进行加载(当用户在搜索输入框中进行了输入) …

  1. import { useState } from 'react'
  2. const names = ['Tim', 'Joe', 'Bel', 'Lee']
  3. export default function Page() {
  4. const [results, setResults] = useState()
  5. return (
  6. <div>
  7. <input
  8. type="text"
  9. placeholder="Search"
  10. onChange={async (e) => {
  11. const { value } = e.currentTarget
  12. // Dynamically load fuse.js
  13. const Fuse = (await import('fuse.js')).default
  14. const fuse = new Fuse(names)
  15. setResults(fuse.search(value))
  16. }}
  17. />
  18. <pre>Results: {JSON.stringify(results, null, 2)}</pre>
  19. </div>
  20. )
  21. }