angular-cli: Angular16 esbuild extremely slow
Command
build, serve
Is this a regression?
- Yes, this behavior used to work in the previous version
The previous version in which this bug was not present was
No response
Description
Wit the advent of Angular 16 I figured I’d give the esbuild builder another try after it not providing much benefit for my project with Angular 15 and initially not working with angular-material back then.
Fully on v16, the esbuild does run. However, instead of faster it is extremely slow compared to the default builder.
I’m talking 658s for ng-serve --proxy-config proxy.config.json
vs 119831ms with the default builder
And 694s for ng build -c=production --subresource-integrity
vs 149683ms with the default builder
At the moment, I’m in the dark as to what could be causing this issue. The only possible hunch would be the iban commonjs module?
Minimal Reproduction
The only things I have changed were in the configuration: adding the -esbuild
suffix to the specified builder and importing the material icons font via the styles array instead of via an scss file.
Package JSON:
{
"name": "esl-apor-portalweb",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"start:proxy": "ng serve --proxy-config proxy.config.json",
"build": "ng build",
"build:prod": "ng build -c=production --subresource-integrity",
"watch": "ng build --watch --configuration development",
"test": "jest --runInBand",
"test:watch": "jest --watch --changedSince master",
"test:local": "jest --coverage",
"test:changed": "jest --coverage --changedSince master",
"docs:json": "compodoc -p ./tsconfig.json -e json -d .",
"storybook": "ng run esl-apor-portalweb:storybook",
"build-storybook": "ng run esl-apor-portalweb:build-storybook",
"prepare": "husky install",
"lint": "ng lint --cache",
"generate:version": "echo 'todo'"
},
"private": true,
"dependencies": {
"@angular/animations": "^16.1.3",
"@angular/cdk": "16.1.3",
"@angular/common": "^16.1.3",
"@angular/compiler": "^16.1.3",
"@angular/core": "^16.1.3",
"@angular/forms": "^16.1.3",
"@angular/material": "16.1.3",
"@angular/material-luxon-adapter": "^16.1.3",
"@angular/platform-browser": "^16.1.3",
"@angular/platform-browser-dynamic": "^16.1.3",
"@angular/router": "^16.1.3",
"@ngx-translate/core": "^15.0.0",
"@ngx-translate/http-loader": "^8.0.0",
"esl-apor-portalapi-v1-api": "^1.3.0",
"iban": "^0.0.14",
"luxon": "^3.3.0",
"material-icons": "^1.13.8",
"rxjs": "~7.8.1",
"tslib": "^2.6.0",
"zone.js": "~0.13.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "^16.1.2",
"@angular-eslint/builder": "16.0.3",
"@angular-eslint/eslint-plugin": "16.0.3",
"@angular-eslint/eslint-plugin-template": "16.0.3",
"@angular-eslint/schematics": "16.0.3",
"@angular-eslint/template-parser": "16.0.3",
"@angular/cli": "~16.1.2",
"@angular/compiler-cli": "^16.1.3",
"@chiragrupani/karma-chromium-edge-launcher": "^2.3.1",
"@compodoc/compodoc": "^1.1.21",
"@storybook/addon-essentials": "^7.0.24",
"@storybook/addon-interactions": "^7.0.24",
"@storybook/addon-links": "^7.0.24",
"@storybook/angular": "^7.0.24",
"@storybook/preset-scss": "^1.0.3",
"@storybook/testing-library": "^0.2.0",
"@types/iban": "^0.0.32",
"@types/jest": "^29.5.2",
"@types/luxon": "^3.3.0",
"@types/node": "^20.3.2",
"@typescript-eslint/eslint-plugin": "^5.60.1",
"@typescript-eslint/parser": "^5.60.1",
"css-loader": "^6.8.1",
"eslint": "^8.43.0",
"eslint-plugin-rxjs": "^5.0.3",
"eslint-plugin-rxjs-angular": "^2.0.1",
"eslint-plugin-storybook": "^0.6.12",
"husky": "^8.0.3",
"jest": "^29.5.0",
"jest-preset-angular": "^13.1.1",
"ngx-translate-testing": "^7.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass": "^1.63.6",
"sass-loader": "^13.3.2",
"storybook": "^7.0.24",
"style-loader": "^3.3.3",
"typescript": "~5.1.6"
}
}
angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"cli": {
"packageManager": "pnpm",
"schematicCollections": ["@angular-eslint/schematics"],
"analytics": false
},
"newProjectRoot": "projects",
"projects": {
"esl-apor-portalweb": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss",
"displayBlock": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "cl",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser-esbuild",
"options": {
"outputPath": "dist/esl-apor-portalweb",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"inlineStyleLanguage": "scss",
"assets": ["src/favicon.ico", "src/assets"],
"styles": [
"src/googleFonts.scss",
"node_modules/material-icons/iconfont/material-icons.scss",
"src/styles.scss",
"src/theme.scss"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all"
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"browserTarget": "esl-apor-portalweb:build:production",
"headers": {
"Content-Security-Policy": "trusted-types angular angular#unsafe-bypass angular#bundler; require-trusted-types-for 'script';"
}
},
"development": {
"browserTarget": "esl-apor-portalweb:build:development",
"headers": {
"Content-Security-Policy": "trusted-types angular angular#unsafe-bypass angular#bundler; require-trusted-types-for 'script';"
}
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "esl-apor-portalweb:build"
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
}
},
"storybook": {
"builder": "@storybook/angular:start-storybook",
"options": {
"browserTarget": "esl-apor-portalweb:build",
"port": 6006,
"compodoc": false,
"configDir": ".storybook"
}
},
"build-storybook": {
"builder": "@storybook/angular:build-storybook",
"options": {
"browserTarget": "esl-apor-portalweb:build",
"outputDir": "__storybook",
"quiet": true,
"compodoc": false
}
}
}
}
},
"schematics": {
"@angular-eslint/schematics:application": {
"setParserOptionsProject": true
},
"@angular-eslint/schematics:library": {
"setParserOptionsProject": true
}
}
}
Exception or Error
No response
Your Environment
Angular CLI: 16.1.2
Node: 18.12.1
Package Manager: pnpm 8.6.5
OS: win32 x64
Angular: 16.1.3
... animations, cdk, common, compiler, compiler-cli, core, forms
... material, material-luxon-adapter, platform-browser
... platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1601.2 (cli-only)
@angular-devkit/build-angular 16.1.2
@angular-devkit/core 16.1.2 (cli-only)
@angular-devkit/schematics 16.1.2 (cli-only)
@angular/cli 16.1.2
@schematics/angular 16.1.2 (cli-only)
rxjs 7.8.1
typescript 5.1.6
Anything else relevant?
I am working on a Windows VDI via Citrix as mandated by the client, which is considerably slower than my own machine. However, the difference is nowhere near big enough to explan a 650+ second ng-serve command.
Package manager is PNPM
My app is split up in
- the start/general code (services, pipes, interceptors, first screen components, …)
- 2 regular modules (layout, shared)
- 3 lazy loaded modules (1 per screen; they all import shared & layout)
Packages that may be relevant:
- @angular/material
- @storybook/angular
- jest-preset-angular
- iban
- luxon
- material-icons
- @ngx-translate
- an auto-generated library package aimed at Angular 15.x for our api calls
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 2
- Comments: 16 (6 by maintainers)
Tried out switching from PNPM to regular NPM first, that shaved almost 600 seconds off the build time, resulting in 59s for ng serve and 70s for ng build. So that ends up in a ~50% improved compilation time if I can count correctly.
If the impact of the package manager is that dramatic, it should probably be mentioned in the guide and might be worth investigating if there is a possible way to mitigate this?
We are using 16.1.5 and Pnpm with Tailwind, and ESBuild.
Even for a very small project, rebuilds are 12 seconds consistently, while it used to be less than a second. Not sure what’s going on
Edit: reverting to the old build: rebuilds are now 1 second, so 12x faster. I assume this is the Sass/EsBuild @import/@use issue. Will have to stick to the old builder until this is somehow resolved. 😦
Edit2: I’m also using pnpm so that’s probably the reason… oh well
Edit3: NG16.2 seems to have resolved the issues
We’re experiencing the same problem. We thought it would be only related to our project because there was nothing similar to find in the web. And we’d never thought that it would be related to pnpm.
Is there any hope that there will be a fix for this in a timely manner? Otherwise we would have to think about migrating away from pnpm.
I’m also facing a similar issue 🤔 not so dramatic but I just compared the previous
webpack
build for our app with the currentesbuild
from16.1.1
. Is this a know issue ? I mean the build time was never great and I hopped that it will be better with this change but going to a new tool which makes it slower is never desired 🤔 . Does anyone know why that might be ?Build Time esbuild on my machine: Cold startup: 120s Rebuilds: 6-12s Build Time webpack on my machine: Cold startup: 102s Rebuilds: 3-6s
Machine specs:
Also, I noticed that pnpm was being used. Is the Angular project also using Sass? Unfortunately, there is a module resolution limitation within the Sass compiler that can cause long resolution times when using either pnpm or yarn PnP. Can you also try using npm as the package manager to see if that has an effect?
@LorinRenodeyn There is a pending PR to update the docs angular/angular#51006 !
@eneajaho Yes npm/yarn were much faster but I have to use pnpm as the app is part of a large monorepo with 10+ apps.
Cheers
Same here. Angular 16 (with es-build and vite), storybook 7. For me it’s 150s - 200s for bootstrap, 50s-60s for each change, about the same as if not worst than what I had before es-build / vite…