This is a simple analysis to compare the performances in compilation time and bundle size between the original Angular build setup and esbuild
.
First run
$ npm run build
> angular-esbuild@0.0.0 build
> ng build
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.
Initial Chunk Files | Names | Raw Size | Estimated Transfer Size
main.09c505bcaf9d2979.js | main | 243.45 kB | 67.57 kB
polyfills.8f8db850ca15da2e.js | polyfills | 36.23 kB | 11.51 kB
runtime.8e5480bc20b419e0.js | runtime | 1.05 kB | 592 bytes
styles.ef46db3751d8e999.css | styles | 0 bytes | -
| Initial Total | 280.72 kB | 79.66 kB
Build at: 2022-02-10T22:10:52.282Z - Hash: eff9defb313aa74d - Time: 13407ms
Second run
$ npm run build
> angular-esbuild@0.0.0 build
> ng build
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.
Initial Chunk Files | Names | Raw Size | Estimated Transfer Size
main.09c505bcaf9d2979.js | main | 243.45 kB | 67.57 kB
polyfills.8f8db850ca15da2e.js | polyfills | 36.23 kB | 11.51 kB
runtime.8e5480bc20b419e0.js | runtime | 1.05 kB | 592 bytes
styles.ef46db3751d8e999.css | styles | 0 bytes | -
| Initial Total | 280.72 kB | 79.66 kB
Build at: 2022-02-10T22:11:04.369Z - Hash: eff9defb313aa74d - Time: 3719ms
After 1st run, Angular caches the build, so the 2nd is a lot faster.
Changes:
- install
@angular-builders/custom-webpack
,esbuild
,esbuild-loader
- customize
angular.json
with custom builder
@@ -18,9 +19,9 @@
"prefix": "app",
"architect": {
"build": {
- "builder": "@angular-devkit/build-angular:browser",
+ "builder": "@angular-builders/custom-webpack:browser",
"options": {
@@ -33,7 +34,11 @@
"styles": [
"src/styles.scss"
],
- "scripts": []
+ "scripts": [],
+ "baseHref": "./",
+ "customWebpackConfig": {
+ "path": "./webpack.config.js"
+ }
- add custom
webpack.config.js
to introduce theESBuildMinifyPlugin
@@ -0,0 +1,11 @@
+const { ESBuildMinifyPlugin } = require("esbuild-loader");
+
+module.exports = (config, options) => {
+ config.optimization.minimizer.unshift(
+ new ESBuildMinifyPlugin({
+ target: "es2015",
+ })
+ );
+
+ return config;
+};
First run
$ npm run build
> angular-esbuild@0.0.0 build
> ng build
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.
Initial Chunk Files | Names | Raw Size | Estimated Transfer Size
main.72764225669f8b40.js | main | 507.04 kB | 121.49 kB
polyfills.7ee2d63f2b229e65.js | polyfills | 39.18 kB | 11.87 kB
runtime.d7e97339efc56b32.js | runtime | 1.07 kB | 597 bytes
styles.ef46db3751d8e999.css | styles | 0 bytes | -
| Initial Total | 547.30 kB | 133.95 kB
Build at: 2022-02-10T22:09:14.110Z - Hash: 1a2773669ad4184f - Time: 4284ms
Warning: bundle initial exceeded maximum budget. Budget 500.00 kB was not met by 47.30 kB with a total of 547.30 kB.
Second run
$ npm run build
> angular-esbuild@0.0.0 build
> ng build
✔ Browser application bundle generation complete.
✔ Copying assets complete.
✔ Index html generation complete.
Initial Chunk Files | Names | Raw Size | Estimated Transfer Size
main.72764225669f8b40.js | main | 507.04 kB | 121.49 kB
polyfills.7ee2d63f2b229e65.js | polyfills | 39.18 kB | 11.87 kB
runtime.d7e97339efc56b32.js | runtime | 1.07 kB | 597 bytes
styles.ef46db3751d8e999.css | styles | 0 bytes | -
| Initial Total | 547.30 kB | 133.95 kB
Build at: 2022-02-10T22:09:35.651Z - Hash: 1a2773669ad4184f - Time: 3993ms
Results:
Setup | Time 1st run | Time 2nd run | Build time | Size main.js | Total size |
---|---|---|---|---|---|
Original | 13407ms | 3719ms | 9688ms | 243.45 kB | 280.72 kB |
esbuild | 4284ms | 3993ms | 291ms | 507.04 kB | 547.30 kB |
The esbuild custom builder reduces the initial build time from 9.5s down to 0.2s. The remaining ~4s I presume is time spent by the Angular CLI to bundle the application.
Worth mentioning that Angular v13 brings the build cache to another level, thus the significant change in time in the 2nd run of the original setup.
The esbuild custom builder, at the moment, produces a larger bundle size, specially for the main.js
file, which is where our application is put.
More effort has to be put on improving the output size, as in current state it can easilly be a no-go.
Introducing esbuild to an Angular CLI application brings significant benefits in build speed. With a bit more of effort it might be possible to bring the bundle size closer to the original setup. Most probably, such changes would be done in custom webpack.config.js
file.
The gains in developer experience, reduced build time in CI Pipelines can result in faster time to ship and less resources spent for builds.