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 …
const DynamicHeader = dynamic(() => import('../components/header'), {loading: () => <header />,})
也就是说React 17 或许没有fallback …
具名暴露
为了动态导入一个命名暴露,你能够通过import()返回的Promise 中返回它 …
// components/hello.jsexport function Hello() {return <p>Hello!</p>}// pages/index.jsimport dynamic from 'next/dynamic'const DynamicComponent = dynamic(() =>import('../components/hello').then((mod) => mod.Hello))
With no SSR
为了加载客户端动态的加载一个组件,你能够使用ssr选项去禁用服务端渲染,这有一种好处(如果外部依赖或者组件依赖于浏览器的API(例如于window)
import dynamic from 'next/dynamic'const DynamicHeader = dynamic(() => import('../components/header'), {ssr: false,})
With external libraries
举个例子,当使用外部库fuse.js进行 模糊查询. 这个模块仅仅在浏览器进行加载(当用户在搜索输入框中进行了输入) …
import { useState } from 'react'const names = ['Tim', 'Joe', 'Bel', 'Lee']export default function Page() {const [results, setResults] = useState()return (<div><inputtype="text"placeholder="Search"onChange={async (e) => {const { value } = e.currentTarget// Dynamically load fuse.jsconst Fuse = (await import('fuse.js')).defaultconst fuse = new Fuse(names)setResults(fuse.search(value))}}/><pre>Results: {JSON.stringify(results, null, 2)}</pre></div>)}
