Code Splitting

Last updated Aug 28, 2021webdevjavascriptterms

Code splitting in web development is a technique to split your code into various smaller bundles which can be loaded on demand or in parallel. Ultimately you want your web apps just lazily load resources currently needed by the user, which can dramatically impove page load speed and hence user experience.

One great feature of the web is that you don’t have to make your visitors download the entire app before they can use it. You can think of code splitting as incrementally downloading the app.

While you might or might not have reduced the overall amount of code in your app, you’ve avoided loading code that the user may never need, and reduced the amount of code needed during the initial load.

Code splitting technique is closely related to following concepts:

  • Dynamic imports - load modules dynamically at runtime in JavaScript.
  • Tree shaking - a form of dead code elimination for preparing production code to achieve significant space savings.
  • Bundling - the process of following imported files and merging them into a single file called bundle.
  • Lazy loading - load content once the user has done something that requires it.
  • Prefetching - resources are downloaded and cached for anticipated future use.
  • Preloading - start loading resources early in the page lifecycle to ensures they are available earlier and less likely to block the page’s render.

Code splitting can be achieved at component or route level. Many frameworks and libraries have their own recommendations on how this should be accomplished within their methodologies.

Supported by bundlers

Most of JavaScript frameworks have their files bundled using module bundlers like Webpack, Parcel, and Rollup which have built-in support for splitting your bundles with little or zero configuration.

Different bundlers work in different ways, the recommended way to introduce code splitting into your app is through the dynamic import(). When bundlers come across this syntax, they automatically start code-splitting your app.

import('./math').then((math) => {
  console.log(math.add(x, y))
})

As the user navigates around in your application and modules are required, bundlers automatically take care of loading child bundles on demand.

Supported in React

If you’re using Create React App, Next, or Gatsby, you will have a Webpack setup out of the box to bundle your app.

In a React application, most of the time you want to split your components. Splitting a component implies the ability to wait for this component to be loaded (showing a fallback during loading) but also to handle errors.

React supports code splitting out of the box with React.lazy and Suspense at component level, but no server-side rendering (SSR) and library splitting.

@loadable/component is a library for loading components with dynamic imports, similar to React.lazy but has support for SSR and library splitting.

import loadable from '@loadable/component'

const OtherComponent = loadable(() => import('./OtherComponent'))

function MyComponent() {
  return (
    <div>
      <OtherComponent />
    </div>
  )
}

React.lazy is the recommended solution when it uses Suspense and it is maintained by React. If you feel limited or if you need SSR, then @loadable/component is the solution.