Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Improving production build time for Angular 7 application

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?

like image 792
Daniel Avatar asked Dec 08 '18 17:12

Daniel


People also ask

Why is my Angular build so slow?

reason: In the Angular 12 version, run ng build, and now the default is production mode. This is a welcome change because it reduces the chance of inadvertently deploying a development build to a production environment, which is much slower and much larger, making it feel like Angular is very slow.

Which command would you use to create a production build of an Angular application?

To build your application for production, use the build command. By default, this command uses the production build configuration. This command creates a dist folder in the application root directory with all the files that a hosting service needs for serving your application.


1 Answers

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)

like image 105
Daniel Avatar answered Sep 17 '22 17:09

Daniel