What exactly esbuild is doing in Angular...?
Angular 15 was recently released. From blog post we know that the Angular team is working on bringing faster builds to the Angular ecosystem.
|
|
It looks like my dream is coming true. For a very long time, I’m waiting for that revolution. Isn’t it going to be great to have building processes as fast I have in React or Vue?!
You know my articles. We need to test it, and we’ll try to investigate what exactly esbuild is doing in the Angular 15 building processes.
App generator
To test build time is good to have a huge app. I don’t have a huge enough app on my GitHub profile. For a moment, let’s assume that I have that app. It’s not the best testing subject. Yes, it’s a real life example and so on, but I cannot scale it. It’s hard to find out how the time of the compilation will change when your number of files are constant.
Today I will use a simple generator, that is able to generate as many components as I want. A very simple components, but to simulate a scale, I just need to generate a few times more components, as usually companies have in their apps.
|
|
Generation is quite simple.
My code is reading file ./src/app/generated/sample.component.ts
, which is a template of component.
Then some code is replaced with the index of the component,
and after that I’m setting everything in AppModule
and AppComponent
.
If you want to check it our, or just double my tests on your machine, here is the galczo5/experiment-angular-15-esbuild repo.
Test results
Number of components | @angular-devkit/build-angular:browser | @angular-devkit/build-angular:browser-esbuild |
---|---|---|
100 (cold) | 11.63s | 5.63s |
100 | 4.94s | 4.44s |
100 | 5.55s | 5.11s |
——————– | ||
1_000 (cold) | 16.34s | 8.25s |
1_000 | 7.83s | 7.38s |
1_000 | 7.19s | 7.23s |
——————– | ||
5_000 (cold) | 60.60s | 33.62s |
5_000 | 38.52s | 36.52s |
5_000 | 43.84s | 34.19s |
——————– | ||
10_000 (cold) | 187.01s | 125.51s |
10_000 | 119.18s | 121.00s |
10_000 | 127.30s | 118.76s |
——————– | ||
20_000 (cold) | 575.86s | 467.61s |
According to my experience with the esbuild, it’s not a full potential of its ability to compile and bundle typescript. Just look at the results that I had almost two years ago when I was preparing my presentation about it.
When I’m using esbuild as a bundler, I rather expect 10 to 50 times faster builds, not time comparable to the webpack build with a cache. So, what esbuild is doing in an Angular building process? It’s time to dig in and check it.
esbuild in Angular sources
First of all,
I moved in Angular repository to tag for version 15.0.1.
I decided to use simple text search to look for all occurrences of esbuild
in repo.
|
|
It’s not the code we are looking for.
This code proves that Angular repo is using esbuild internally as a bundler (check out usages in BUILD.bazel
files).
The code that we need is not in the main Angular repository.
You’ll find it in angular/angular-cli.git.
|
|
For sure, esbuild
is used for css optimization and style related stuff. What about typescript?
File ./packages/angular_devkit/build_angular/src/builders/browser-esbuild/esbuild.ts
looks promising,
I’ve started with it during my analysis.
|
|
build
function from esbuild
is used in bundle
method, in this case I would be good to create a simple repository, add console.log
of options passed to the build
and check what is configured there.
|
|
There is no magic, bot typescript, and styles are compiled with the esbuild
.
Both of them are using plugins made by Angular team.
I have that strange feeling that, maybe these plugins create a bottleneck in the whole process.
It’s easy to verify.
I changed the code in
node_modules/@angular-devkit/build-angular/src/builders/browser-esbuild/esbuild.js
to remove all plugins.
I had
to pass through the styles
because entry point of value { styles: 'angular:styles/global;styles' }
is not possible
to process without these plugins.
Wow! The results are stunning!
Number of components | @angular-devkit/build-angular:browser | @angular-devkit/build-angular:browser-esbuild | esbuild - no plugins |
---|---|---|---|
100 (cold) | 11.63s | 5.63s | 1.32s |
1_000 (cold) | 16.34s | 8.25s | 1.26s |
5_000 (cold) | 60.60s | 33.62s | 1.47s |
10_000 (cold) | 187.01s | 125.51s | 2.40s |
20_000 (cold) | 575.86s | 467.61s | 1.31s |
The bundle of course is not working, because I removed a very important part of a compilation process, but still, I would like to have that fast build processes.
Now we know that the problem is in the plugins.
Summary
This post is quite long, so I decided to stop here. We know that the problem is in esbuild plugins.
We have a few of them:
- angular-compiler
- angular-global-styles
- angular-sass
- angular-css-resource
In next articles I will try
to investigate where might be the problem and why it’s not that easy to compile Angular-based apps with esbuild
.