DEV Community

Cover image for Web Performance Case Study: webpack splitChunks
Paul Golubkov
Paul Golubkov

Posted on

Web Performance Case Study: webpack splitChunks

Hello there! I've just finished optimizing my last commercial project, and now, I want to share what I've learned. So, I've decided to start a series of articles.

In this article, I want to share with you knowledge about webpack's optimization.splitChunks functionality. That functionality is a part of the webpack since version 4 before It was an external plugin called SplitChunksPlugin. It provides a way to split your bundle into several parts.

When can it be useful?

It can help you at least in two kinds of cases:

  • When you have a single entry, you can separate vendors for a better cache strategy
  • When you have many entries, you can separate common parts

Let's take a look at examples of both cases.

Single entry

Let's imagine that we have a bundle that contains react app. It includes JavaScript code from an app directory and several npm packages from the node_modules directory:

Initial bundle for single entry

Our bundle's name contains a contenthash for cache validation in the browser. When we change some code in our app, we create a new bundle that includes a different contenthash, and users will download it again. Frequently we'll change code inside our app directory and not change our npm dependencies, but our users will anew download the whole bundle. Here is where splitChunks can help us.

We can separate our bundle into two parts:

  • code inside app directory
  • code inside node_modules

In this way, when we'll change a code inside the app directory, our users will download only that part.

Let's do it!

To do that we need to add that code to our webpack config:

{
  entry: {
    ... // here is your entry
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendors: {
          test: /node_modules/,
          chunks: 'initial',
          filename: 'vendors.[contenthash].js',
          priority: 1,
          maxInitialRequests: 2, // create only one vendor file
          minChunks: 1,
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Now our bundles will looks like that:

Final bundle for single entry

How you can see we don't reduce bundle size, but we save some kb of traffic for our users in case when we change only one part of code.

You can get more control of what will be added to bundle by passing function instead of regexp as test:

{
  entry: {
    ... // here is your entry
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        react: {
          test(module) {
            // `module.resource` contains the absolute path of the file on disk.
            return (
              module.resource &&
              module.resource.includes('node_modules/react')
            );
          },
          chunks: 'initial',
          filename: 'react.[contenthash].js',
          priority: 1,
          maxInitialRequests: 2,
          minChunks: 1,
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

In this case will be created bundle that will contain only code of react package.

Many entries

Assume we have three entries like that:

Initial bundles for many entries

We can move common code to separate bundle:

{
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendors: {
          test: /node_modules/,
          chunks: 'initial',
          filename: 'vendors.[contenthash].js',
          priority: 1,
          maxInitialRequests: 2,
          minChunks: 3, // count of entries
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Now our bundles may looks like that:

Final bundles of many entries

We didn't reduced size of javascript needed for page, but we reduced total size of bundles and now we can cache common bundle across pages, and it's cool!

That's it

Now you know how you can use the splitChunks to improve UX in your app, read documentation for more detais and try it out!

Thank you for reading! This is the first article of the series about web performance, click on the Follow button to see future articles and motivate me to write them.

Follow me on Twitter: https://twitter.com/paulcodes_tech, there I'll share with you some tips and tools for Frontend developers.

Answer me in comments:

  • Did this article was helpful?
  • Do you like the pictures I provide?
  • Will you try it out?
  • Do you want me to provide a repository for this and future articles?
  • Any other feedback :)

Top comments (0)