Webpack — Build Performance Pitfall of using SASS with CSS Modules

Will Po
jsdownunder
Published in
3 min readAug 1, 2017

Many people looking to combine the power of SASS with modularised stylesheets will use CSS Modules.

It’s an obvious choice.

When using Webpack as your bundler, you’ll likely use sass-loader to transpile the SASS. An example of the Webpack loaders configuration used to do this:

{
test: /\.sass$/,
use: [
{
loader: 'style-loader',
options: {
sourceMap: true,
},
},
{
loader: 'css-loader',
options: {
sourceMap: true,
modules: true,
importLoaders: 3,
localIdentName: '[folder]--[local]--[hash:base64:2]',
}
},
'postcss-loader',
'resolve-url-loader',
{
loader: 'sass-loader',
options: {
sourceMap: true,
indentedSyntax: true,
}
}
]
},
{
test: /\.sass$/,
use: [
{
loader: 'style-loader',
options: {
sourceMap: true,
},
},
{
loader: 'css-loader',
options: {
sourceMap: true,
modules: true,
importLoaders: 3,
localIdentName: '[folder]--[local]--[hash:base64:2]',
}
},
'postcss-loader',
'resolve-url-loader',
{
loader: 'sass-loader',
options: {
sourceMap: true,
indentedSyntax: true,
}
}
]
},

The Problem — Exponentially Increasing Build Times

Part of the problem with sass-loader (which uses node-sass underneath), is that transpiled SASS files are not cached. Also, when sass-loader is used with CSS Modules, every component’s stylesheet is modularised, and so each of these will spawn its own SASS process, and your dual/quad core CPU will try to run all these processes simultaneously with tremendous overhead. Most likely these stylesheets will import some common SASS modules (eg. breakpoints, mixins, variables, colours, etc), and since there’s no cached transpilation, this means these common SASS modules will get transpiled to CSS over and over and over and over…

Exponentially Increasing Build Times

For our team, this led to exponential increases in the start up time of our Webpack Dev Server from a few seconds when the project was started, to about 3–6 minutes after a few months worth of new components and changes.

Most of the time, we don’t need to restart our dev server due to the hot-reloading that we’ve configured. But often we’ll have to do one of: switch to another branch which requires yarn to be run, switch to another repo/branch to do a code review, restart the computer or restart the app for some reason…

Bad Developer Experience

Needless to say, every restart was a massive drain on productivity, momentum, and the developer experience (ie. dev happiness), which further affects productivity! — and so we took drastic action!

Our Solution

Get rid of SASS!

Ok — well, what do you use instead?

PostCSS / CSSNext.

Most of the stuff you want to do in SASS, you can already do with tomorrow’s CSS syntax with the help of PostCSS and CSSNext.

After converting all our component’s stylesheets from SASS to CSS, our build time has pretty much dropped by 50% to about 1.5 minutes.

1.5 minutes! Still much higher than desired, but a massive improvement in productivity for us.

Conclusion

If you’re starting a new project and looking to use CSS Modules, strongly consider using PostCSS/CSSNext from the start, and don’t use SASS at all. You will save yourself a lot of time down the long run!

On the other hand, if you are already using CSS Modules with SASS and are experiencing increasing build times, take comfort in knowing that if you take the plunge (and short-term pain) to convert all your SASS to CSS, you can reduce the build time by ~50%!

--

--