Blitz 尚在 beat 阶段! 🎉 预计会在今年的 Q3 季度发布 1.0
Back to Documentation Menu

代码分割

Topics

Jump to a Topic

Blitz 自动为你的每个页面优化你的 JavaScript 包,因此你的用户将会在指定的路 由下仅下载所需的资源(而不需你付出任何额外的工作!)。这项技术被熟称为 代码分割

如果需要在页面内拆分或延迟加载资源,Blitz 支持 ES2020 JavaScript 的动态 import()。此时 你可以动态导入 JavaScript 模块(React 组件,库等)来使用。你可以将动态导入 理解为将代码拆分为可管理的代码块的另一种方法。

一个你可能想这样做的原因是,当一个页面上的功能依赖一个非常大的库,你不想要 让用户的浏览器在不需要的使用下载它(且并不是所有用户在这个页面都会使用)。 例如,你可以使用动态导入来当用户在页面某个位置点击一个按钮或勾选一个选项时 ,动态地加载这个库。这可以让每个用户访问最初页面时的加载体验很好且很快。

另一个可以从动态导入来获益的场景是,使用仅在浏览器上用到的库(或许它使用 window 对象无需事先检查是否可用)。在这种情况下,动态导入这个库会防止 Blitz 在执行服务端渲染时报出错误。

基本使用

在下面的示例中,../components/hello 模块将会被动态导入到页面中:

import { dynamic } from "blitz"

const DynamicComponent = dynamic(() => import("../components/hello"))

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponent />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home

DynamicComponent 将会成为 ../components/hello 返回的默认组件。它像常规 React 组件一样工作,你可以在像往常一样将 props 传递给它。

注意:在 import('path/to/component') 中,路径必须明确地被说明。它 不能是一个模板字符串或一个变量。此外,import() 必须在 dynamic() 中调 用,以便 Next.js 能够将 Webpack 包/模块 ID 与特定的 dynamic() 调用进行 匹配,并在渲染之前预先加载他们。dynamic() 无法在 React 渲染过程中使用 ,因为它需要在模块的顶层进行标记以进行预加载才能工作,类似于 React.lazy

命名导出

如果动态组件不是默认导出的,你也可以使用命名导出。考虑有一个导出时名为 Hello../components/hello.js 模块:

export function Hello() {
  return <p>Hello!</p>
}

要动态导入 Hello 组件,你可以从 import() 返回 的 Promise 中将其返回,如下所示:

import { dynamic } from "blitz"

const DynamicComponent = dynamic(() =>
  import("../components/hello").then((mod) => mod.Hello)
)

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponent />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home

带有自定义加载组件

可以添加一个可选的 loading 组件,以在加载动态组件时呈现加载状态。例如:

import { dynamic } from "blitz"

const DynamicComponentWithCustomLoading = dynamic(
  () => import("../components/hello"),
  {
    loading: () => <p>...</p>,
  }
)

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithCustomLoading />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home

没有 SSR

你可能并不总是希望在服务器端包含一个模块。例如,当模块包含仅在浏览器中可用 的库时。

看看下面这个例子:

import { dynamic } from "blitz"

const DynamicComponentWithNoSSR = dynamic(
  () => import("../components/hello3"),
  {
    ssr: false,
  }
)

function Home() {
  return (
    <div>
      <Header />
      <DynamicComponentWithNoSSR />
      <p>HOME PAGE is here!</p>
    </div>
  )
}

export default Home

Idea for improving this page? Edit it on GitHub.