Improving production build time for Angular 7 application

Daniel picture Daniel · Dec 8, 2018 · Viewed 16.7k times · Source

My application takes a very long time to build for production using ng build --prod

Sometimes it even fails with

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

Is there something I can do to reduce the build time?

Answer

Daniel picture Daniel · Dec 8, 2018

There are some things that can be done to reduce the build time.

Increase the memory limit of the build process

The build command is executed by node where a single process has a maximum memory limit of 1.76 GB on 64bit machines. It can be increased by adding the --max-old-space-size argument to the build command

Since this argument must be passed to the node process itself, the command must be run directly with node. An example allocation 4096 MB (4GB) of RAM to the process would be:

node --max-old-space-size=4096 ./node_modules/@angular/cli/bin/ng build

Increasing the memory limit will also prevent the "heap out of memory" error.

There does appear to be a limit to how much memory the process uses. A project of mine had it's build time significantly reduced by a memory increase to 12GB - but increasing it to 32GB gave no further improvement.

Fix references to node_modules in .scss files

Referencing external stylesheets from node_modules using relative paths has a negative performance impact on the build process and should be avoided.

The build process uses Webpack's sass-loader, which supports a syntax where the location of node_modules is referenced with the tilde ~.

Using the tilde instead of the relative path greatly reduces build time. So instead of importing external css stylesheets with

import "../../../../../node_modules/x/whatever.css"

use

import "~node_modules/x/whatever.css"

Production optimizations

By default the production build uses the configuration from your angular.json file. The default values are

"production": {
  "fileReplacements": [
    {
      "replace": "src/environments/environment.ts",
      "with": "src/environments/environment.prod.ts"
    }
  ],
  "optimization": true,
  "outputHashing": "all",
  "sourceMap": false,
  "extractCss": true,
  "namedChunks": false,
  "aot": true,
  "extractLicenses": true,
  "vendorChunk": false,
  "buildOptimizer": true
}

Do not divert from the production build defaults unless you have a very good reason.

These are a big part of keeping the build time low (espescially disabling sourceMap and enabling buildOptimizer).

Update your Angular CLI version

The Angular CLI teamb continuously improves the speed of the build process.

Notibly the upgrade in build performance from version 6 to 7 is substantial, so keeping the @angular/cli library up to date is always a good idea.

External libraries

To have a fast building application you need to be very careful with which libraries you import.

Many popular libraries such as jQuery, lodash and moment are very large in size and not properly optimized for the Webpack building process.

Look for libraries that supports Webpack's Tree-Shaking to allow the build process to only bundle the parts of the library that is actually used in your application.

Also, don't fall into the trap of adding an entire utility library (such as lodash) if you only need to use a single function from it (like _get()).

Compressing assets

Compressing assets (often images) is largely a trivial task (just google "compress images online"), and it can increase the performance of the build process and the application itself.

Hardware optimizations

Since Javascript is a single-threaded the benefits of having multiple CPU cores won't speed up the build process.

In fact, if you monitor your CPU during the build you will see a single core is under 100% load almost during the entire process.

If you are regulary building your application with production flag as part of your continuous integration setup, you may consider using a machine equipped with high single-threaded performance (for benchmarks, see cpubenchmark.net)