How We Sped Up Our Webpack (TailwindCSS) Build By 74%

pavelloz

Paweł Kowalski

Posted on March 22, 2021

How We Sped Up Our Webpack (TailwindCSS) Build By 74%

Since Github Actions became a thing, I became interested in saving precious seconds in our plan by optimizing assets build time. As long as it didn't exceed 60 seconds, there was little motivation, but once it did, I said enough is enough.

Our build step runs two commands:

  • npm ci
  • npm run build

We use babel and TailwindCSS. Using simple methods, I discovered that CSS and JS take about the same time to build.

Benchmark: Webpack build took 64 seconds, whole build took 91 seconds.

Replacing babel-loader + terser with esbuild loader

The first thing I did was replace babel-loader and Terser (minification tool) with esbuild-loader. This made our JS compile around 12 times faster, it went down to 1.4 seconds. It was a good start.

Result: Webpack build took 40 seconds (down from 64), whole build took 65 seconds.

Configuring Tailwind

The second optimization had to do something with CSS because that's where most of the build time now lay. I visited the TailwindCSS documentation to find out how to decrease build size.

The template we base our projects on uses a style guide with predefined colors, sizes, etc., so we don't need some of the configuration from TailwindCSS. Knowing this, here's what I did:

  1. Moved colors configuration outside extend, which disabled all the built-in colors from the build. This made a huge difference in development file size (10.5MB → 4MB).
  2. Moved spacing configuration outside extend
  3. Disabled corePlugins

I had to bring some of these back because we used them in a couple of places. After these changes, I considered TailwindCSS optimization done.

The file size of development CSS went down from 10.5MB to 3.9MB, which is a big deal (depending on the developer's connection speed) if you are sending your CSS on every CSS change. It does not happen often when working with TailwindCSS, but it was still a welcome improvement for everyone using our pos-cli sync command.

Result: Webpack build took 26 seconds (down from 40), whole build took 49 seconds.


Read about TailwindCSS optimization in their documentation:

Disabling PostCSS processing

The last step was to disable PostCSS processing of CSS pulled in from node_modules.

Before, it was pretty naive — everything went through all the CSS loaders:

{
  test: /(\.css)$/,
  use: [
    MiniCssExtractPlugin.loader,
    { loader: 'css-loader', options: { url: false } },
    'postcss-loader',
  ],
},
Enter fullscreen mode Exit fullscreen mode

I split it into two so that node_modules are processed only by css-loader, and application CSS is processed by PostCSS first.

{
  test: /(\.css)$/,
  include: /node_modules/,
  use: [
    MiniCssExtractPlugin.loader,
    { loader: 'css-loader', options: { url: false } }
  ],
},
{
  test: /(\.css)$/,
  exclude: /node_modules/,
  use: [
    MiniCssExtractPlugin.loader,
    { loader: 'css-loader', options: { url: false } },
    'postcss-loader',
  ],
},
Enter fullscreen mode Exit fullscreen mode

Result: Webpack build took 17 seconds (down from 26), whole build took 39 seconds.

That's all :)

This journey was one of those creative ones where you fiddle around, find gains in various places, and they add up. In this case, they added up to 52 seconds of savings for every build. And we build a lot, so this improves our developer experience and lowers the cost of CI.

Action Webpack build time (seconds) Whole build time (seconds)
At the start 64 91
Using esbuild loader 40 65
Configuring Tailwind 26 49
Disabling PostCSS processing 17 39

In the following article, I will report how development speedup is going because the TailwindCSS team just released the experimental TailwindCSS JIT, which might improve live development even further.

Read more

If you are interested in more performance oriented content, follow me and I promise to deliver original, or at least effective methods of improving your website.

💖 💪 🙅 🚩
pavelloz
Paweł Kowalski

Posted on March 22, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related