I have a simple app, initialized by angular-cli
.
It display some pages relative to 3 routes. I have 3 components. On one of this page I use lodash
and Angular 2 HTTP modules to get some data (using RxJS Observable
s, map
and subscribe
). I display these elements using a simple *ngFor
.
But, despite the fact my app is really simple, I get a huge (in my opinion) bundle package and maps. I don't talk about gzip versions though but size before gzipping. This question is just a general recommendations inquiry.
Some tests results:
ng build
Hash: 8efac7d6208adb8641c1 Time: 10129ms chunk {0} main.bundle.js, main.bundle.map (main) 18.7 kB {3} [initial] [rendered]
chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [initial] [rendered]
chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 kB {4} [initial] [rendered]
chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 3.96 MB [initial] [rendered]
chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 bytes [entry] [rendered]
Wait: 10Mb vendor bundle package for such a simple app?
ng build --prod
Hash: 09a5f095e33b2980e7cc Time: 23455ms chunk {0} main.6273b0f04a07a1c2ad6c.bundle.js, main.6273b0f04a07a1c2ad6c.bundle.map (main) 18.3 kB {3} [initial] [rendered]
chunk {1} styles.bfdaa4d8a4eb2d0cb019.bundle.css, styles.bfdaa4d8a4eb2d0cb019.bundle.map, styles.bfdaa4d8a4eb2d0cb019.bundle.map (styles) 154 kB {4} [initial] [rendered]
chunk {2} scripts.c5b720a078e5464ec211.bundle.js, scripts.c5b720a078e5464ec211.bundle.map (scripts) 128 kB {4} [initial] [rendered]
chunk {3} vendor.07af2467307e17d85438.bundle.js, vendor.07af2467307e17d85438.bundle.map (vendor) 3.96 MB [initial] [rendered]
chunk {4} inline.a345391d459797f81820.bundle.js, inline.a345391d459797f81820.bundle.map (inline) 0 bytes [entry] [rendered]
Wait again: such a similar vendor bundle size for prod?
ng build --prod --aot
Hash: 517e4425ff872bbe3e5b Time: 22856ms chunk {0} main.95eadabace554e3c2b43.bundle.js, main.95eadabace554e3c2b43.bundle.map (main) 130 kB {3} [initial] [rendered]
chunk {1} styles.e53a388ae1dd2b7f5434.bundle.css, styles.e53a388ae1dd2b7f5434.bundle.map, styles.e53a388ae1dd2b7f5434.bundle.map (styles) 154 kB {4} [initial] [rendered]
chunk {2} scripts.e5c2c90547f3168a7564.bundle.js, scripts.e5c2c90547f3168a7564.bundle.map (scripts) 128 kB {4} [initial] [rendered]
chunk {3} vendor.41a6c1f57136df286f14.bundle.js, vendor.41a6c1f57136df286f14.bundle.map (vendor) 2.75 MB [initial] [rendered]
chunk {4} inline.97c0403c57a46c6a7920.bundle.js, inline.97c0403c57a46c6a7920.bundle.map (inline) 0 bytes [entry] [rendered]
ng build --aot
Hash: 040cc91df4df5ffc3c3f Time: 11011ms chunk {0} main.bundle.js, main.bundle.map (main) 130 kB {3} [initial] [rendered]
chunk {1} styles.bundle.css, styles.bundle.map, styles.bundle.map (styles) 155 kB {4} [initial] [rendered]
chunk {2} scripts.bundle.js, scripts.bundle.map (scripts) 128 kB {4} [initial] [rendered]
chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 2.75 MB [initial] [rendered]
chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 bytes [entry] [rendered]
So a few questions for deploying my app on prod:
- Why are the vendor bundles so huge?
- Is tree shaking properly used by
angular-cli
? - How to improve this bundle size?
- Are the .map files required?
- Are the testing features included in bundles? I don't need them in prod.
- Generic question: what are the recommanded tools to pack for prod? Maybe
angular-cli
(using Webpack in the background) is not the best option? Can we do better?
I searched many discussions on Stack Overflow, but I haven't found any generic question.
Lodash can contribute a bug chunk of code to your bundle depending on how you import from it. For example:
Personally I still wanted smaller footprints from my utility functions. E.g.
flatten
can contribute up to1.2K
to your bundle, after minimization. So I've been building up a collection of simplified lodash functions. My implementation offlatten
contributes around50 bytes
. You can check it out here to see if it works for you: https://github.com/simontonsoftware/micro-dashIf you have run
ng build --prod
- you shouldn't havevendor
files at all.If I run just
ng build
- I get these files:The total size of the folder is ~14MB. Waat! :D
But if I run
ng build --prod
- I get these files:The total size of the folder is 584K.
One and the same code. I have enabled Ivy in both cases. Angular is 8.2.13.
So - I guess you didn't add
--prod
to your build command?This did reduce the size in my case:
Size after running this command reduced from 1.7MB to 1.2MB, but not enough for my production purpose.
I work on facebook messenger platform and messenger apps need to be lesser than 1MB to run on messenger platform. Been trying to figure out a solution for effective tree shaking but still no luck.
I have a angular 5 + spring boot app(application.properties 1.3+) with help of compression(link attached below) was able to reduce the size of main.bundle.ts size from 2.7 MB to 530 KB.
Also by default --aot and --build-optimizer are enabled with --prod mode you need not specify those separately.
https://stackoverflow.com/a/28216983/9491345
Use latest angular cli version and use command ng build --prod --build-optimizer It will definitely reduce the build size for prod env.
This is what the build optimizer does under the hood:
The build optimizer has two main jobs. First, we are able to mark parts of your application as pure,this improves the tree shaking provided by the existing tools, removing additional parts of your application that aren’t needed.
The second thing the build optimizer does is to remove Angular decorators from your application’s runtime code. Decorators are used by the compiler, and aren’t needed at runtime and can be removed. Each of these jobs decrease the size of your JavaScript bundles, and increase the boot speed of your application for your users.
Note : One update for Angular 5, the
ng build --prod
automatically take care of above process :)Update October 2018
Since this answer got a lot of traction, I thought it would be best to update it with newer Angular optimizations:
ng build --prod --build-optimizer
is a good option for people using less than Angular v5. For newer versions, this is done by default withng build --prod
Some claims that using AOT compilation can reduce the vendor bundle size to 250kb. However, in BlackHoleGalaxy's example, he uses AOT compilation and is still left with a vendor bundle size of 2.75MB with
ng build --prod --aot
, 10x larger than the supposed 250kb. This is not out of the norm for angular2 applications, even if you are using v4.0. 2.75MB is still too large for anyone who really cares about performance, especially on a mobile device.There are a few things you can do to help the performance of your application:
1) AOT & Tree Shaking (angular-cli does this out of the box)
2) Using Angular Universal A.K.A. server-side rendering (not in cli)
3) Web Workers (again, not in cli, but a very requested feature)
see: https://github.com/angular/angular-cli/issues/2305
4) Service Workers
see: https://github.com/angular/angular-cli/issues/4006
You may not need all of these in a single application, but these are some of the options that are currently present for optimizing Angular performance. I believe/hope Google is aware of the out of the box shortcomings in terms of performance and plans to improve this in the future.
Here is a reference that talks more in depth about some of the concepts i mentioned above:
https://medium.com/@areai51/the-4-stages-of-perf-tuning-for-your-angular2-app-922ce5c1b294