Web Dev Efficiency: Achieving Faster Builds and Lower Memory Load with Webpack
Tags: webpack, performance, memory
Published: 2023-09-19 12:52:37

We have been using Webpack forever (2015 to be exact).
We tried to move to vite, snowpack, esbuild, bun, turbopack, but none of them can bundle everything that we need to bundle yet, like our backends, frontends, widgets, plugins, and scripts.

As we can't leave Webpack, we found many ways to optimize it.
Making it faster and to consume fewer memory.

## Making it fast and consuming less memory

The first thing you can do is to have different configurations for development and production.

We use `webpack-merge` to merge our `common` configurations that are the same for development and production.
We have the following structure

```jsx
webpackCommonConfig.ts
webpackDevConfig.ts
webpackProdConfig.ts
```

### Source Map

We need to compile modern JavaScript code to be compatible with older browsers.
The source map does the mapping from the generated code to the source code. This is useful for debugging, development and error monitoring in production.
We can use a faster source map in development to speed up bundling.

`devtool: 'cheap-module-source-map',`

`cheap-module-source-map` provides the best cost benefit for source map in development.

### Pathinfo

[outputpathinfo](https://webpack.js.org/configuration/output/#outputpathinfo)

```jsx
output: {
   pathinfo: false,
},
```

`pathinfo: false` will output fewer comments in bundles making bundling faster.

### Babel-loader vs esbuild-loader vs SWC-Loader

Deciding what loader will compile your TypeScript code can speed up bundling a lot.
Babel is the default one, but it is slow.
Esbuild and SWC are faster, but only SWC has a Relay plugin that we need.

So, we use swc-loader to compile our TypeScript code.

### writeToDisk: true

```jsx
devServer: {
   devMiddleware: {
      writeToDisk: true,
    },
}
```

Webpack Dev Server will default to bundling everything in memory.
This is faster, but if you have a very big frontend as we have, it will consume a lot of memory.
One of our frontends was consuming more than 5GB of RAM, when we switched to `writeToDisk: true`, it started consuming fewer than 1GB of RAM.
We didn't notice any performance loss with this change.
The computer became even more responsive with less memory pressure.

### Persistent cache

```jsx
cache: {
    type: 'filesystem',
  },
```

We opt-in Webpack persistent cache using the filesystem, to avoid consuming a lot of memory, and to also speed up rebuilds.
If we stop our Webpack bundling process and start it over, it will catch up from the last cache point.

### Lazy Compilation

```jsx
experiments: {
      lazyCompilation: {
        imports: true,
        entries: true,
      },
      cacheUnaffected: true,
    },
``` 
Lazy Compilation will lazy bundle/compile entry points and dynamic imports.
This will make your bundle compile faster, and it will also use less memory as we need to bundle less.
Every page/route is a dynamic import, so it is lazily compiled at Woovi.
This makes sure we only compile the routes we are working on.

## Key Takeaways

Every optimization was done over time.
We dig into documentation, issues, articles, and code to find the right configuration that fit better our use cases.
We also used memory and CPU profiles to find bottlenecks to focus our optimization efforts.

I do believe there is even more optimization to be done.

If you have even more Webpack or bundling tricks comment on the article.

---
Woovi
[Woovi](https://www.woovi.com) is a Startup that enables shoppers to pay as they like. To make this possible, Woovi provides instant payment solutions for merchants to accept orders.

If you want to work with us, we are [hiring](https://woovi.com/jobs/)!

---
Photo by <a href="https://unsplash.com/@zoltantasi?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Zoltan Tasi</a> on <a href="https://unsplash.com/photos/QxjEi8Fs9Hg?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>