106

After making some changes in my TypeScript files, each build takes over 20 minutes. I run this command: ng build --output-path=..\..\static\angularjs.

If I run it in Microsoft PowerShell, it needs 25 - 30 seconds. This is a lot of time.

Enviroment

  • Windows 10
  • 8 GB-Ram
  • PyCharm 64
  • MS PowerShell

How can I speed this up?

gmds
  • 19,325
  • 4
  • 32
  • 58
michael-mammut
  • 2,595
  • 5
  • 28
  • 46

12 Answers12

85

My app took 28secs to build, but I've reduced the time to 9secs. Usings this flag

ng build --source-map=false

you can see the difference in time comparing the time:

ng build --stats-json 

ng build --stats-json --source-map=false

source map is intended only for debugging, Hope it helps

Neuron
  • 5,141
  • 5
  • 38
  • 59
  • 54
    If you remove any way to debug the TS files , this doesn't help a developer, does it? – Mark Langer Dec 22 '17 at 11:18
  • 13
    I'm a developer and this is extremely helpful. I don't need debug information 100% of the time (and I'll still get some errors that will be self explanatory). I expect this to save a lot of time when I'm actually *developing* new stuff. For me compile time for a full build went from 35 to 23 seconds. For an `ng serve` it went from 22 to 16 seconds. – Simon_Weaver May 09 '18 at 23:58
  • And having used this for a couple days I'm also realizing that usually having a single file to debug in chrome (main.js) is actually often much easier than many typescript files - especially if you want to set breakpoints. The speed increase for recompilation when a small change is made - down from 2-3 seconds to about half a second. The bottleneck now is the time it takes Chrome to parse and display the page - which hopefully will be much faster with the upcoming Ivy renderer. – Simon_Weaver May 12 '18 at 22:17
  • 1
    Wow, man. I owe you a beer! This also works with ng serve and speeds up refreshes. – gilm Sep 03 '18 at 07:02
  • I have such message. The option '--source-map' is not registered with the serve command – Артур Гудиев Nov 07 '18 at 16:05
  • 6
    With newer versions it is --sourcemaps=false – user1008139 Dec 27 '18 at 15:29
  • 1
    @АртурГудиев this was for `ng build`, not `ng serve` – thynctank Feb 22 '19 at 21:18
  • 5
    Uh... Source Map is not just for debugging. It's also for being able to support production with real code references instead of minified variable names,e tc. – Tom McKearney Aug 12 '19 at 16:06
  • you dont add prod as a parameter ? prod is very important because it reduces runtime sleed cause it compresses more code and files. – numerical25 Mar 25 '21 at 00:15
  • Didn't help. After I enter "ng build" I get like 10-15 s of pause, and then starts "generating modules etc..." And, this second part is also same as before. – Dalibor Jul 01 '21 at 10:59
  • 1
    CI/CD systems can benefit from this too – Some random IT boy Oct 29 '21 at 13:18
43

This reduced my build time to 50%

          "optimization": false,
          "outputHashing": "none",
          "sourceMap": false,
          "extractCss": true,
          "namedChunks": false,
          "showCircularDependencies": false,
          "aot": true,
          "extractLicenses": false,
          "statsJson": false,
          "progress": false,
          "vendorChunk": true,
          "buildOptimizer": false,
dota2pro
  • 7,220
  • 7
  • 44
  • 79
  • 14
    The Comment sounds helpful, could you please help by explaining each option, i did look through the ng build documentation and couldn't find the explanations helpful. – TheViralGriffin Dec 16 '19 at 15:06
  • 2
    @TheViralGriffin https://angular.io/cli/build see options section – dota2pro Dec 17 '19 at 08:51
  • 2
    @dota2pro what i meant was, for example there is one option called "extractLicenses", in the documentation it says that "extractLicenses" "Extracts all licenses in a separate file". In this scenario which licences are we talking about. Hence i suggested, if possible and if you are aware what those option do, you could brief them so that people visiting the post might find it extremely helpful. – TheViralGriffin Dec 17 '19 at 10:37
  • 4
    @dota2pro where do you place this configuration options ? In the angular.json file ? – Viocartman Mar 02 '20 at 10:32
  • 3
    I would leave in "showCircularDependencies": true, because this be the root for terrible code – Simon Dragsbæk Jul 29 '20 at 08:26
  • +1 This is a great answer that helped me a lot to optimize the dev build. Everyone wondering where to place and how to use those properties, along with some stats, can read my own answer below – afrish Jul 01 '21 at 11:49
  • note that 'showCircularDependencies' option deprecated and 'extractCss' removed in angular 14. – Amir Azizkhani Aug 15 '22 at 05:17
  • @AmirAzizkhani 11, not 14. https://stackoverflow.com/questions/67209871/extracting-css-into-js-with-angular-11-deprecated-extractcss – Matthew Kooshad Jul 14 '23 at 01:02
21

I've found that for me, this issue was solved by using the watch flag, i.e.

ng build --watch=true

This runs constantly, and automatically builds files only when saved. It has dropped my build time from 8 sec to <1 sec for small changes in code, since it only generates .js files for what actually changed.

From https://angular.io/guide/deployment

The ng build command generates output files just once and does not serve them.

The ng build --watch command will regenerate output files when source files change. This --watch flag is useful if you're building during development and are automatically re-deploying changes to another server.

You should probably use ng build with the necessary options when you are building for production so that the necessary optimizations are completed.

Stephen Turner
  • 7,125
  • 4
  • 51
  • 68
nivlac
  • 380
  • 2
  • 10
  • 3
    I believe `watch` mode is not considered a build in this question. OP search for way to speed up overall build process for deployment, not in development. – Tomas Aug 08 '18 at 20:37
  • 7
    Thanks for the feedback Tomas. I added this answer because I could imagine someone else coming to this question, and this answer being just what they needed (like it was for me). Could you explain why you believe `watch` mode isn't considered a build? OP talked about "some changes in TypeScript Files" so I thought this would be a valuable answer. – nivlac Aug 16 '18 at 00:25
  • in `watch` mode Angular will rebuild only chunks of changed code, thus it's considerably faster, however does not reflect overall production build process, when all files need to be compiled, tree-shaked and bundled. Thus disabling `watch` will speed up development process (on local development each file change can be assigned to single chunk) of each subsequent build (but not the first one), it will completely not affect production build. But yeah, `some change` as OP mentions may indicate he refer to development (not releasing/building itself) process. – Tomas Aug 16 '18 at 10:34
  • Please just add a note in answer that this will affect development process build speed, not building deployment and I'll be happy to took back my down vote. – Tomas Aug 16 '18 at 10:36
  • Hi @Tomas, I've improved the answer for nivlac. Do you think this better answers the question? – Stephen Turner Aug 16 '18 at 13:23
  • Thanks Stephen and Tomas! This was my first SO answer, so your feedback is very much appreciated :) – nivlac Aug 16 '18 at 23:08
  • --watch is useful to test the final build and you need to make changes on the fly, but the initial build (the first time you run it) will take the same amount of time, I wouldn't recommend this as a solution. – alexOtano Jan 24 '22 at 21:32
18

Based on others' answers I created my own configuration, which reduced dev build time three times.

  1. In the angular.json I created a new profile called "development" under projects.<my-project-name>.architect.build.configurations:

    "development": {
      "optimization": false,
      "outputHashing": "none",
      "sourceMap": true,
      "namedChunks": false,
      "aot": true,
      "extractLicenses": false,
      "statsJson": false,
      "progress": true,
      "vendorChunk": true,
      "buildOptimizer": false
    },
    "production": {
      ...
    

    Here I enable source maps. If you don't need them, you can set sourceMap flag to false, it will reduce build time even more.

  2. In the package.json file I added a new script called watch:

    "scripts": {
      ...
      "watch": "ng build --watch --configuration development"
    }
    
  3. Then I just have to run in the command line:

    npm run watch
    

    and see the build taking much less than before and also on each change it rebuilds everything even quicker.

My final stats are the following:

  • Default settings: 77 sec
  • With source maps: 25 sec
  • Without source maps: 21 sec
afrish
  • 3,167
  • 4
  • 30
  • 38
  • I changed `aot` to `false` and it worked very very very well, 20Sec to 500miliSec – aniran mohammadpour Jan 21 '22 at 13:24
  • 1
    @aniranmohammadpour Thanks for the tip, need to try it too. Be careful though, because you may have different build results/errors with and without AOT. So after going through multiple dev build cycles, you still have to build it at least once with AOT turned on, as you would want it on prod – afrish Jan 24 '22 at 09:48
11

According to https://github.com/angular/angular-cli/issues/6795 using --build-optimizer=false speeds up the build.

Chris Richner
  • 2,863
  • 2
  • 26
  • 38
10

If this answer helps you, please leave a comment on what specific advice was helpful!

I recently upgraded from Angular 8 to Angular 13. My build time was comparable (~10 minutes in both Angular 8 and Angular 13), but I struggled with my rebuild time (i.e. I use --watch while I develop; if I change only a few files, Angular 8 was recompiling in <10 seconds; Angular 13 required another 10 minutes!).

I used angular.json (see below for a screenshot) to specify "aot":false and I saw much better rebuild times (back to ~8-10 seconds) -- this option is the same as angular-cli ng build command's --aot=false.

I'm adding my answer because currently no other answer suggests trying to use "aot:false. In fact, many of the most popular answers explicitly suggest trying "aot":true! Those answers aren't wrong (in fact, they identify options that improve performance, like "sourceMap":false.) But for me, "aot":false was the gamechanger.

Also, I recognize the benefits of "AOT" (Ahead-of-Time compilation), for example "faster rendering in the browser". I still use "AOT" ("aot":true) for my production builds; but my answer here is focused on development, where I use --watch to re-build on file changes, so I want a fast re-build, and I don't mind "slower rendering in the browser".

Some helpful resources (I will add more if I find more):

  • This comment suggests AOT compilation might be slower than JIT compilation, which may be the reason "aot":false works for me
  • This comment might help you profile your build process (to find the bottleneck/troubleshoot long build times) using node --inspect and chrome://inspect
  • This comment has more tips on profiling with NG_BUILD_PROFILING=1

Other tips that may improve build performance:

Some related stuff (more experimental / may not be helpful) :

  • Blogposts like this one suggest you could use your own builder, like esbuild, to see build performance improvements -- but this is more experimental and may not support "native ways" of doing things in Angular (i.e. the templateUrl property). Also they could come at a cost (i.e. larger bundle sizes)
  • This video from Google Chrome Developers talks about principles for "startup performance" , however it's >1 year old, and focuses bundle size and other best practices; so the video may make suggestions that decrease build performance (for other tradeoffs like smaller bundles or easier debugging).

EDIT I set "aot":false` in my angular.json as shown in the below screenshot. Notice the location/path in the JSON is:

root>projects>{craft-app}>architect>build>configurations>{development}

... where {craft-app} is the specific name of the angular project you need to build and {development} is the specific name for the configuration you want to use and specify in the -c argument, as in:

ng build craft-app -c=development

screenshot of angular.json structure showing the angular.json root>projects>{craft-app}>architect>build>configurations>{development} object has aot false value

Nate Anderson
  • 18,334
  • 18
  • 100
  • 135
6

This reduced my build time to 70%

      "optimization": false,
      "outputHashing": "none",
      "sourceMap": false,
      "extractCss": true,
      "namedChunks": false,
      "showCircularDependencies": false,
      "aot": true,
      "extractLicenses": false,
      "statsJson": false,
      "progress": false,
      "vendorChunk": true,
      "buildOptimizer": false
ani
  • 61
  • 1
  • 2
3

You can use node parameter --max_old_space_size like

node --max_old_space_size=4096 ./node_modules/.bin/ngbuild --prod --build-optimizer

But I prefer to set it up via environment:

NODE_OPTIONS=--max-old-space-size=4096

It speedup our build process on CI pipeline twice.

GetoX
  • 4,225
  • 2
  • 33
  • 30
  • One of the easiest and effective solutions. To set the appropriate value for max_old_space_size check official documentation https://nodejs.org/api/cli.html#cli_max_old_space_size_size_in_megabytes. E.g. 'On a machine with 2GB of memory, consider setting this to 1536 (1.5GB) to leave some memory for other uses and avoid swapping.' – Aliaksei Maniuk May 07 '21 at 23:20
3

Adding an answer which might be relevant only to the more recent Angular versions (10 and later)

I discovered that the mixing CommonJS and AMD dependencies is the culprit in my case.

The angular build process issues these kinds of warnings to indicate that you are in this situation:

Warning: xxxxxx.ts depends on 'yyyyyy.js'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies

My own rebuild time was unbearable at almost 6 minutes in this state - note that this is a rebuild - meaning it's just for saving one modified typescript file:

Build at: 2021-05-28T07:39:58.559Z - Hash: 5f8c96f22c3daf60faa2 - Time: 234429ms

But when I removed the offensive references, initial build time went down to about 80 seconds, and rebuild times went down to 7-8 seconds.

Admittedly, you might not always be able to remove references to offensive modules, but in my case I was able to do that for local debugging, and to keep them when deploying. This sped up my development considerably.

Aviad P.
  • 32,036
  • 14
  • 103
  • 124
  • I'm using rxjs-compat first operator to be able to do .first() on an Observable (which wraps the next in a promise). Any idea if there's a non-commonjs equivalent of that? Scourged through google but no success... – DFSFOT Jun 06 '21 at 23:12
  • 1
    @DFSFOT would `firstValueFrom` work for you? https://rxjs.dev/api/index/function/firstValueFrom – Trevor Nov 09 '21 at 06:25
2

While in dev mode you can change this flag for your development to

"buildOptimizer": false

This worked for me . Angular 7 .

I.Tyger
  • 715
  • 1
  • 8
  • 19
1

Remove all optimizations for prod build

enter image description here

The time decreases from one hour to 6 min in my project

C1X
  • 665
  • 4
  • 14
  • 25
-1

Don't forget to always keep a close eye on what else your machine is doing and monitor overall CPU usage.

For instance if like me you tend to never close VS Code windows you'll eventually end up with hundreds open which can actually really slow things down. You'll be timing a slow Angular build while VSCode in parallel is running through thousands of the same files at the same time trying to check everything.

I just closed probably hundreds of windows and immediately I've noticed my laptop fans coming on much less.

I'd also recommend adding your work directory into exclusions for your virus checking software. Of course it's up to you to judge if that may not be safe in your environment.

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • This is hardly an answer. You could answer this to _any_ performance related StackOverflow thread. – Jeppe Mar 11 '23 at 19:16