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.js
export function Hello() {
return <p>Hello!</p>
}
// pages/index.js
import 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>
<input
type="text"
placeholder="Search"
onChange={async (e) => {
const { value } = e.currentTarget
// Dynamically load fuse.js
const Fuse = (await import('fuse.js')).default
const fuse = new Fuse(names)
setResults(fuse.search(value))
}}
/>
<pre>Results: {JSON.stringify(results, null, 2)}</pre>
</div>
)
}