Blitz is pivoting to framework agnostic toolkit. Click to learn more.
🚀Announcing Flightcontrol - Easily Deploy Blitz.js and Next.js to AWS 🚀
Back to Documentation Menu

Code Splitting

Topics

Jump to a Topic

Blitz automatically optimizes your JavaScript bundles for each page, so your users will only download the required assets for a given route (without any extra effort on your part!). This technique is known as code splitting.

In the event you need to split or lazy-load assets within a page, Blitz supports ES2020 dynamic import() for JavaScript. With it you can import JavaScript modules (React components, libraries, etc.) dynamically and work with them. You can think of dynamic imports as another way to split your code into manageable chunks.

One reason you may want to do this is when a feature on page relies on a very large library that you don't want the user's browser to have to download unless they need it (and not all visitors to the page will need it). You can use dynamic imports to load the library only after the user has clicked a button or toggled an option somewhere on the page, for example. This helps keep the initial page load nice and fast for everyone.

Another scenario that may benefit from dynamic imports is using a library that only works in the browser (perhaps it uses the window object without first checking if it's available). In this case, dynamically importing the library will prevent it from throwing an error when Blitz performs server-side rendering.

Basic usage

In the following example, the module ../components/hello will be dynamically loaded by the page:

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 will be the default component returned by ../components/hello. It works like a regular React Component, and you can pass props to it as you normally would.

Note: In import('path/to/component'), the path must be explicitly written. It can't be a template string nor a variable. Furthermore the import() has to be inside the dynamic() call for Next.js to be able to match webpack bundles / module ids to the specific dynamic() call and preload them before rendering. dynamic() can't be used inside of React rendering as it needs to be marked in the top level of the module for preloading to work, similar to React.lazy.

With named exports

If the dynamic component is not the default export, you can use a named export too. Consider the module ../components/hello.js which has a named export Hello:

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

To dynamically import the Hello component, you can return it from the Promise returned by import(), like so:

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

With custom loading component

An optional loading component can be added to render a loading state while the dynamic component is being loaded. For example:

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

With no SSR

You may not always want to include a module on server-side. For example, when the module includes a library that only works in the browser.

Take a look at the following example:

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.