Closed kemsky closed 3 years ago
It's this commit a fix (or possible could have positive impact) for this case? https://github.com/angular/angular-cli/commit/f90a8324b46bd96e87a7b889a74aab432a391015
But what does it exactly mean that node modules just be immutable? Because angular will change it on the first build (ngcc compile) but will that be a problem ? Because this will be done already before webpack really starts to do it's thing right?
Version 12.1.0
has been released which contains several performance improvements. We also introduced an experimental file system cache which should improve the second/warm build quite a lot. You can opt-in using the NG_PERSISTENT_BUILD_CACHE=1
environment variable.
Please update using ng update @angular/cli @angular/core
.
If the issue persist please report back providing one of the following;
@alan-agius4 I'm seeing reductions from 40 > 30 seconds for my build with this change.
Given that this is experimental I'm assuming once in a while we might need to clear the cache. Do you have any thoughts on how stable this feature is at this time?
For anyone curious, the cache is stored in node_modules\.cache\angular-webpack
Also for anybody on Windows this is the correct way to set environmental variables in Powershell.
$env:NG_PERSISTENT_BUILD_CACHE=1
ng serve
I am not seeing much improvement after upgraded to 12.1.0 comparing to 12.0.5. It's still slow if you compare to V11. However, hasn't crashed with OOM yet, will keep monitoring. I am using cross env to set environment variable "cross-env NG_PERSISTENT_BUILD_CACHE=1 ng serve"
@zwjohn, if itβs still noticeable slower compared to v11, please provide one of the below as otherwise weβll be unable to look into your issue.
@alan-agius4 For starter, here is a component that I removed a space from the ts file, it took 15-16 seconds to recompile for the first change while running ng serve, and around 10-11 seconds after first time. Note that all tests were just to remove a space from ts file. It was less than 5 seconds in V11. The reproduction for OOM is pretty hard to do, since there is no specific trigger I noticed, it happened a few times while making changes to the project during local development , it just crashed, however, it was with 12.05, not yet crashed for 12.1. I will continue to monitor.
My problem is with ng serve , the slow recompilation of ng serve is impacting development speed. node v14.17.0 npm v6.14.13
Lazy Chunk Files | Names | Size ****_module_ts.js | - | 132.76 kB
60 unchanged chunks
Build at: 2021-06-26T02:07:18.541Z - Hash: f27b25b4ae1c532eca8b - Time: 15864ms
β Compiled successfully.
Build and Serve configuration in angular.json, I will monitor about OOM crash.
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"aot": true,
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
"src/assets/favicon/favicon.ico",
"src/assets/favicon/favicon-16x16.png",
"src/assets/favicon/favicon-32x32.png",
"src/assets/favicon/favicon.ico",
"src/assets",
{
"glob": "_redirects",
"input": "src",
"output": "/"
},
"src/manifest.webmanifest"
],
"styles": [
"src/styles.scss",
"node_modules/@ctrl/ngx-emoji-mart/picker.css"
],
"scripts": [],
"allowedCommonJsDependencies": [
"lodash",
"@swimlane/dragula",
"chart.js",
"angular-calendar",
"calendar-utils/date-adapters/date-fns",
"contra/emitter",
"crossvent",
"dom-plane",
"dom-set",
"@mattlewis92/dom-autoscroller",
"dragula"
]
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "5mb",
"maximumError": "8mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "150kb",
"maximumError": "200kb"
}
],
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"outputHashing": "all",
"serviceWorker": true,
"ngswConfigPath": "ngsw-config.json",
"optimization": true,
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "production"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "build"
},
"configurations": {
"production": {
"browserTarget": "build:production"
},
"development": {
"browserTarget": "build:development"
}
},
"defaultConfiguration": "development"
},
package.json Angular related libs
"dependencies": { "@angular-eslint/schematics": "12.1.0", "@angular-material-components/datetime-picker": "6.0.3", "@angular-material-components/moment-adapter": "6.0.0", "@angular/animations": "12.1.0", "@angular/cdk": "12.1.0", "@angular/common": "12.1.0", "@angular/compiler": "12.1.0", "@angular/core": "12.1.0", "@angular/flex-layout": "12.0.0-beta.34", "@angular/forms": "12.1.0", "@angular/material": "12.1.0", "@angular/material-moment-adapter": "12.1.0", "@angular/platform-browser": "12.1.0", "@angular/platform-browser-dynamic": "12.1.0", "@angular/router": "12.1.0", "@angular/service-worker": "12.1.0", }
"devDependencies": { "@angular-devkit/build-angular": "12.1.0", "@angular/cli": "12.1.0", "@angular/compiler-cli": "12.1.0", "@angular/language-service": "12.1.0", "@angularclass/hmr": "3.0.0", "@types/dompurify": "2.2.2", "@types/jasmine": "3.7.7", "@types/jquery": "^3.5.5", "@types/lodash": "4.14.170", "@types/node": "15.12.2", "@types/prismjs": "1.16.5", "codelyzer": "6.0.2", "cross-env": "7.0.3", "jasmine-core": "3.7.1", "jasmine-spec-reporter": "7.0.0", "karma": "6.3.4", "karma-chrome-launcher": "3.1.0", "karma-jasmine": "4.0.1", "karma-jasmine-html-reporter": "1.6.0", "protractor": "7.0.0", "replace-in-file": "6.2.0", "ts-node": "10.0.0", "tslint": "6.1.3", "typescript": "4.2.4", "webpack-bundle-analyzer": "4.4.2" }
I tried to generate CPU profile by using NG_BUILD_PROFILING=1 and kept getting errors, and it builds fine without setting this environment variable
Option "extractCss" is deprecated: Deprecated since version 11.0. No longer required to disable CSS extraction for HMR.
node --trace-deprecation ...
to show where the warning was created)To generate a build profile you can you use the below.
node -βcpu-proof node_module/@angular/cli/lib/init.js serve
If are are comparing rebuild times, try to do something meaningful such as changing a string value adding a console.log or something that effects the final bundle, adding only a space in a file will indeed be slower in v12.
Also, the first rebuild will always be slower than later rebuilds.
Side note: it appears that you are experiencing a different issue from the original reported were it was related to increase in non incremental build times. Therefore, I do suggest to open an new issue to for your problem and provide all the necessary info and keep this issue focused on the original reported problem.
@alan-agius4 Still can't build in prod mode on my project ... JS heap out of memory, works in v11. How can I help you ? This is a private project for a company I'm working for, I am unable to share it with you unfortunately.
profile I have sent them by email to alan.agius4@gmail.com
angular.json the build for plex3 works, for production-plex3, it doesn't
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"defaultProject": "app",
"newProjectRoot": "projects",
"projects": {
"app": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"preserveSymlinks": true,
"outputPath": "www",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json",
"assets": [
{
"glob": "**/*",
"input": "src/assets",
"output": "assets"
},
{
"glob": "**/*.svg",
"input": "node_modules/ionicons/dist/ionicons/svg",
"output": "./svg"
},
{
"glob": "**/*",
"input": "src/app/home/assets",
"output": "assets"
},
{
"glob": "**/*",
"input": "src/app/synoptique/assets",
"output": "assets"
},
{
"glob": "**/*",
"input": "src/app/teleprogrammation/assets",
"output": "assets"
},
{
"glob": "**/*",
"input": "src/app/grapheur/assets",
"output": "assets"
},
{
"glob": "**/*",
"input": "src/app/cde/assets",
"output": "assets"
},
"src/manifest.webmanifest"
],
"styles": ["src/styles/styles.global.scss"],
"aot": false,
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
"sourceMap": true,
"optimization": false,
"namedChunks": true
},
"configurations": {
"plex3": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.development.ts"
}
]
},
"ic-plex3": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.ic.ts"
}
]
},
"production-plex3": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.production.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb"
}
],
"serviceWorker": true,
"ngswConfigPath": "ngsw-config.json"
},
"ci": {
"progress": false
}
},
"defaultConfiguration": ""
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "app:build"
},
"configurations": {
"production-plex3": {
"browserTarget": "app:build:production-plex3"
},
"plex3": {
"browserTarget": "app:build:plex3"
},
"ci": {
"progress": false
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "app:build"
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
}
},
"ionic-cordova-build": {
"builder": "@ionic/angular-toolkit:cordova-build",
"options": {
"browserTarget": "app:build"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
}
}
},
"ionic-cordova-serve": {
"builder": "@ionic/angular-toolkit:cordova-serve",
"options": {
"cordovaBuildTarget": "app:ionic-cordova-build",
"devServerTarget": "app:serve"
},
"configurations": {
"production": {
"cordovaBuildTarget": "app:ionic-cordova-build:production",
"devServerTarget": "app:serve:production"
}
}
}
}
}
},
"cli": {
"defaultCollection": "@ionic/angular-toolkit",
"analytics": false
},
"schematics": {
"@ionic/angular-toolkit:component": {
"prefix": "app",
"styleext": "scss",
"lintFix": true
},
"@ionic/angular-toolkit:page": {
"styleext": "scss"
},
"@schematics/angular:directive": {
"prefix": "app"
}
}
}
Version
12.1.0
has been released which contains several performance improvements. We also introduced an experimental file system cache which should improve the second/warm build quite a lot. You can opt-in using theNG_PERSISTENT_BUILD_CACHE=1
environment variable.Please update using
ng update @angular/cli @angular/core
.If the issue persist please report back providing one of the following;
- CPU profile, memory snapshots and angular.json configuration
- Reproduction (Even shared privately).
I'm seeing a regression(?) with 12.1 and I'm not sure if I should open that separately or if it might be related to this. With 12.0 I was able to build whatever V8 decided was appropriate for a machine with 4GB of RAM, but with 12.1 I had to bump --max_old_space_size
up to 3GB. It's possible we were almost at that line and an unrelated package update is what actually pushed us over the limit.
I have the CI running with NG_BUILD_CACHE=1
already (hopefully that makes sense). Is there something that NG_PERSISTENT_BUILD_CACHE=1
would provide over the other option?
I can try profiling, but I'll have to see when I'd have time to do that since bumping the memory is the bandaid I have time for right now :sweat_smile:
NG_BUILD_CACHE
is enabled by default, and is mainly used to opt-out all build caching, this supersedes NG_PERSISTENT_BUILD_CACHE
.NG_PERSISTENT_BUILD_CACHE
is disable by default, and can be used to opt-in to cache the entire build on disk, which will make the 2nd build warm. Typically you don't want this on CI since typically the "cache" will be discarded with node_modules
after every CI run.That being said, this issue is about build times and not memory, hence if you are experiencing memory issues please file a new issue providing all the necessary profiles and/or a reproduction.
@Yohandah, let's please keep this issue on build times. If you are experiencing memory issues please file a new issue and attach the memory heap profiles for v11 and v12.
Thanks.
@alan-agius4 you closed the issue concerning build crashes and said it was now tracked here ........ ?
@Yohandah, are you referring to version 9 issue (https://github.com/angular/angular-cli/issues/16860#issuecomment-852031823)? I stated that this issue (https://github.com/angular/angular-cli/issues/20792) is for build-time performance.
@alan-agius4 Well could you reopen #16860 then ? the title says "& out of memory errors"
, and my issue is a memory error; or should I open a new issue ?
@alan-agius4 Well could you reopen #16860 then ? the title says
"& out of memory errors"
, and my issue is a memory error; or should I open a new issue ?
Most of the context in #16860 is no longer relevant in version 12, since that was dedicated to version 9. Hence please open a new issue with profiles from v11 and v12. Thanks.
also for us using NG_PERSISTENT_BUILD_CACHE is a lot faster
production build goes from 80+ seconds to 20+ seconds
and also none production builds do gain like 28 seconds to 20 seconds.
so using that flag the production build are quite close to the none (debug) builds..
Unfortunately, we do not see much improvement with NG_PERSISTENT_BUILD_CACHE
, I tried with and without but compared to 11.0.2 it's still much slower. I could live with production or even development build to be slower, but the much slower watch
really hurts during development... :/
command | 11.0.2 | 12.1.0 | 12.1.0 with NG_PERSISTENT_BUILD_CACHE 1st | 12.1.0 with NG_PERSISTENT_BUILD_CACHE 2nd |
---|---|---|---|---|
develop build | ~83s | ~98s | ~100s | ~106s |
production build | ~180s | ~270s | ~240s | ~225s |
watch | ~92s | 140s + 48s* | 106s + 43s* | - |
recompile (main bundle**) | ~13s | ~22s | ~21s | - |
* initial watch always immediately triggers a recompile for whatever reason ** main bundle has about 6-7mb in watch mode
angular.json:
{
"version": 1,
"projects": {
"app": {
"projectType": "application",
"schematics": {
"@nrwl/angular:component": {
"style": "less",
"changeDetection": "OnPush"
}
},
"root": "apps/app",
"sourceRoot": "apps/app/src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "apps/app/extra-webpack.config.js",
"mergeStrategies": {
"optimization.minimizer": "replace",
"externals": "replace"
}
},
"outputPath": "dist/apps/app",
"index": "apps/app/src/index.html",
"main": "apps/app/src/main.ts",
"polyfills": "apps/app/src/polyfills.ts",
"tsConfig": "apps/app/tsconfig.app.json",
"preserveSymlinks": true,
"aot": true,
"allowedCommonJsDependencies": [
"jstimezonedetect",
"css-element-queries",
"fastdom",
"dragula",
"contra/emitter",
"crossvent",
"dom-autoscroller",
"dom-plane",
"dom-set",
"pdfjs-dist",
"zone.js/dist/zone-error"
],
"assets": [
{
"glob": "**/*",
"input": "apps/app/src/assets/images",
"output": "/images"
},
{
"glob": "**/*",
"input": "apps/app/src/assets/icons",
"output": "/icons"
},
{
"glob": "**/*",
"input": "apps/app/src/assets/static",
"output": "/static"
},
{
"glob": "**/*",
"input": "apps/app/src/assets/translations/messages",
"output": "/translations"
},
{
"glob": "properties.js",
"input": "apps/app/src/assets/",
"output": "/"
},
{
"glob": "**/*",
"input": "libs/annotations/src/assets/translations/messages",
"output": "/translations/annotations"
},
{
"glob": "**/*",
"input": "node_modules/pdfjs-dist/cmaps",
"output": "/worker-libs/pdf-cmaps/"
},
{
"glob": "pdf.worker.min.js",
"input": "node_modules/pdfjs-dist/build",
"output": "/worker-libs/"
},
{
"glob": "**/*",
"input": "libs/common-components/src/assets/translations/messages",
"output": "/translations/common"
},
{
"glob": "**/*",
"input": "libs/common-components/src/assets/images",
"output": "/images"
},
{
"glob": "**/*",
"input": "libs/common-components/src/assets/icons",
"output": "/icons"
},
{
"glob": "**/*",
"input": "libs/internal-components/src/assets/images",
"output": "/images"
}
],
"scripts": [
"node_modules/pdfjs-dist/build/pdf.min.js",
"libs/annotations/src/assets/libs/fabric.js",
"node_modules/systemjs/dist/s.js",
"node_modules/systemjs/dist/extras/named-register.js",
"node_modules/systemjs/dist/extras/amd.js"
],
"stylePreprocessorOptions": {
"includePaths": [
"libs/common-components/src/assets/styles",
"apps/app/src/assets/styles",
"libs/app/shared/src/lib/assets/styles"
]
},
"styles": [
"node_modules/quill/dist/quill.core.css",
"node_modules/quill/dist/quill.bubble.css",
"node_modules/quill/dist/quill.snow.css",
"node_modules/pdfjs-dist/web/pdf_viewer.css",
"node_modules/dragula/dist/dragula.min.css",
"libs/common-components/src/assets/styles/material-theme-custom.less",
"libs/common-components/src/assets/styles/app.less",
"apps/app/src/assets/styles/styles.less",
"apps/app/src/assets/styles/app-material.less"
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "apps/app/src/environments/environment.ts",
"with": "apps/app/src/environments/environment.prod.ts"
}
],
"optimization": {
"scripts": false,
"styles": true,
"fonts": true
},
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "4mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "6kb",
"maximumError": "10kb"
}
]
},
"development": {
"buildOptimizer": false,
"optimization": false,
"vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
}
},
"defaultConfiguration": "development"
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "app:build"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"apps/app/tsconfig.app.json",
"apps/app/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**",
"!apps/app/**/*"
]
}
},
"test": {
"builder": "@nrwl/jest:jest",
"options": {
"jestConfig": "apps/app/jest.config.js",
"passWithNoTests": true,
"silent": true
}
}
}
},
"common-components": {
"projectType": "library",
"root": "libs/common-components",
"sourceRoot": "libs/common-components/src",
"prefix": "cc",
"architect": {
"build": {
"builder": "@nrwl/angular:package",
"options": {
"tsConfig": "libs/common-components/tsconfig.lib.json",
"project": "libs/common-components/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "libs/common-components/tsconfig.lib.prod.json"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"libs/common-components/tsconfig.lib.json",
"libs/common-components/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**",
"!libs/common-components/**/*"
]
}
},
"test": {
"builder": "@nrwl/jest:jest",
"options": {
"jestConfig": "libs/common-components/jest.config.js",
"passWithNoTests": true,
"silent": true
}
},
"storybook": {
"builder": "@nrwl/storybook:storybook",
"options": {
"uiFramework": "@storybook/angular",
"port": 4400,
"config": {
"configFolder": "libs/common-components/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
},
"build-storybook": {
"builder": "@nrwl/storybook:build",
"options": {
"uiFramework": "@storybook/angular",
"outputPath": "dist/storybook/common-components",
"config": {
"configFolder": "libs/common-components/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
}
},
"schematics": {
"@nrwl/angular:component": {
"style": "less",
"changeDetection": "OnPush"
}
}
},
"internal-components": {
"projectType": "library",
"root": "libs/internal-components",
"sourceRoot": "libs/internal-components/src",
"prefix": "ic",
"architect": {
"build": {
"builder": "@nrwl/angular:package",
"options": {
"tsConfig": "libs/internal-components/tsconfig.lib.json",
"project": "libs/internal-components/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "libs/internal-components/tsconfig.lib.prod.json"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"libs/internal-components/tsconfig.lib.json",
"libs/internal-components/tsconfig.spec.json",
"libs/internal-components/.storybook/tsconfig.json"
],
"exclude": [
"**/node_modules/**",
"!libs/internal-components/**/*"
]
}
},
"test": {
"builder": "@nrwl/jest:jest",
"options": {
"jestConfig": "libs/internal-components/jest.config.js",
"passWithNoTests": true,
"silent": true
}
},
"storybook": {
"builder": "@nrwl/storybook:storybook",
"options": {
"uiFramework": "@storybook/angular",
"port": 4400,
"config": {
"configFolder": "libs/internal-components/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
},
"build-storybook": {
"builder": "@nrwl/storybook:build",
"options": {
"uiFramework": "@storybook/angular",
"outputPath": "dist/storybook/internal-components",
"config": {
"configFolder": "libs/internal-components/.storybook"
}
},
"configurations": {
"ci": {
"quiet": true
}
}
}
},
"schematics": {
"@schematics/angular:component": {
"style": "less",
"changeDetection": "OnPush"
}
}
},
"annotations": {
"projectType": "library",
"root": "libs/annotations",
"sourceRoot": "libs/annotations/src",
"prefix": "app",
"architect": {
"build": {
"builder": "@nrwl/angular:package",
"options": {
"tsConfig": "libs/annotations/tsconfig.lib.json",
"project": "libs/annotations/ng-package.json"
},
"configurations": {
"production": {
"tsConfig": "libs/annotations/tsconfig.lib.prod.json"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"libs/annotations/tsconfig.lib.json",
"libs/annotations/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**",
"!libs/annotations/**/*"
]
}
},
"test": {
"builder": "@nrwl/jest:jest",
"outputs": [
"coverage/libs/annotations"
],
"options": {
"jestConfig": "libs/annotations/jest.config.js",
"passWithNoTests": true,
"silent": true
}
}
}
}
},
"cli": {
"defaultCollection": "@nrwl/angular"
},
"schematics": {
"@nrwl/angular:application": {
"unitTestRunner": "jest",
"e2eTestRunner": "cypress"
},
"@nrwl/angular:library": {
"unitTestRunner": "jest"
},
"@nrwl/angular:component": {
"style": "less"
}
}
}
System info:
OS Name: Microsoft Windows 10 Enterprise
OS Version: 10.0.19041 N/A Build 19041
OS Build Type: Multiprocessor Free
System Type: x64-based PC
Processor(s): 1 Processor(s) Installed.
[01]: Intel64 Family 6 Model 142 Stepping 10 GenuineIntel ~1792 Mhz
BIOS Version: HP Q78 Ver. 01.06.00, 03.01.2019
Total Physical Memory: 32Β 611 MB
I could send the cpu profiles if needed, but I am not allowed to share them (or the repo) publicly. Just let me know where I should send them :)
@mrucelum, you are using builders which are not supported by the Angular tooling team. This causes a migration that adjusts the options to provide equivalent behavior from prior to the update not to run. Ideally these 3rd party builders should provide their own migration.
You need to adjust the options by hand to retain the existing behavior. For more information, see the breaking changes section within the release notes: https://github.com/angular/angular-cli/releases/tag/v12.0.0
@alan-agius4 Thanks for link!
So if I understand you correctly, I have to adjust the configuration
section of my angular.json
manually, because I am using custom builders, right?
I checked the breaking changes and if I understand them correctly, with this addition to the angular.json
:
"configurations": {
[...]
"development": {
"optimization": false,
"buildOptimizer": false,
"sourceMap": true,
"extractLicenses": false,
"namedChunks": true,
"vendorChunk": true
}
},
I have the old default values (we had "aot": true
before) already in place (when it comes to develop build and watch).
But this is the exact configuration I did my tests with. So I guess I am missing something in addition? Or does the custom builder need to adapt something (I mean something I cannot influence by just adapting my angular.json
)?
Thanks again :)
In the above table, you mentioned watch
are you using ng build --watch
?, Can you also try to replace the 3rd party builder with a supported builder @angular-devkit/build-angular:browser
?
You can send the CPU profiles to alan.agius4[at]gmail.com.
It seems to be indeed the @angular-builders/custom-webpack:browser
that causes the slow down π²
ng build --watch
1) with @angular-devkit/build-angular:browser
Initial Chunk Files | Names | Size
vendor.js | vendor | 7.86 MB
main.js | main | 6.66 MB
scripts.js | scripts | 677.03 kB
polyfills.js | polyfills | 213.39 kB
styles.css | styles | 150.33 kB
runtime.js | runtime | 14.33 kB
| Initial Total | 15.55 MB
Build at: 2021-07-01T11:06:38.058Z - Hash: cd684dc7fcbc67560f0f - Time: 76208ms
2) with @angular-builders/custom-webpack:browser
Initial Chunk Files | Names | Size
vendor.js | vendor | 6.67 MB
main.js | main | 6.66 MB
scripts.js | scripts | 677.03 kB
polyfills.js | polyfills | 213.39 kB
styles.css | styles | 150.33 kB
runtime.js | runtime | 13.67 kB
| Initial Total | 14.36 MB
Build at: 2021-07-01T11:43:51.105Z - Hash: 34bdac20b292943b28c9 - Time: 107267ms
β Browser application bundle generation complete.
β Index html generation complete.
15 unchanged chunks
Build at: 2021-07-01T11:44:36.147Z - Hash: e7860c484b03f51d78f9 - Time: 43856ms
3) with @angular-builders/custom-webpack:browser and without custom terser config in the referenced webpack config
Initial Chunk Files | Names | Size
vendor.js | vendor | 6.67 MB
main.js | main | 6.66 MB
scripts.js | scripts | 677.03 kB
polyfills.js | polyfills | 213.39 kB
styles.css | styles | 150.33 kB
runtime.js | runtime | 13.67 kB
| Initial Total | 14.36 MB
Build at: 2021-07-01T11:12:49.818Z - Hash: 1ac2e18b2a871e0bf8a0 - Time: 103078ms
β Browser application bundle generation complete.
β Index html generation complete.
15 unchanged chunks
Build at: 2021-07-01T11:13:32.438Z - Hash: b8d53eea43833e670b2b - Time: 41681ms
4) with @angular-builders/custom-webpack:browser with empty webpack config
Initial Chunk Files | Names | Size
vendor.js | vendor | 7.86 MB
main.js | main | 6.66 MB
scripts.js | scripts | 677.03 kB
polyfills.js | polyfills | 213.39 kB
styles.css | styles | 150.33 kB
runtime.js | runtime | 13.67 kB
| Initial Total | 15.55 MB
Build at: 2021-07-01T11:17:38.033Z - Hash: 223bbb0d807f62d6e34f - Time: 109983ms
β Browser application bundle generation complete.
β Index html generation complete.
15 unchanged chunks
Build at: 2021-07-01T11:18:26.881Z - Hash: b76731d2fe86fcc023e6 - Time: 47707ms
btw this is the custom webpack config:
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
externals: {
'fabric': 'window'
},
plugins: [new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en|de/)],
optimization: {
minimizer: [new TerserPlugin({
terserOptions: {
ecma: undefined,
warnings: false,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
output: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: true,
keep_fnames: false,
safari10: false
},
})]
}
};
Conclusion:
However... we need the custom webpack config as we do not want to have all the unnecessary moment locales in our bundle and also need to be able to specify 'fabric' as external for some legacy lib we are using. So I guess I will head over to the @angular-builders/custom-webpack:browser project and file an issue there. Thanks a lot @alan-agius4 !
Success! I found steps to get good performance when using @angular-builders/custom-webpack
TLDR; before upgrading angular, remove all traces of custom-webpack
so the migrations run in full, and then re-install custom-webpack
Here is what worked for me, starting with an Angular 11 project:
@angular-builders/custom-webpack:browser
with @angular-devkit/build-angular:browser
(and delete the customWebpackConfig
block)@angular-builders/custom-webpack
from package.jsonnode_modules
and package_lock.json
npm install
ng update @angular/cdk @angular/cli @angular/core
@angular-builders/custom-webpack
back into package.jsonnpm install
@angular-builders/custom-webpack:browser
and restored the customWebpackConfig
block.I confirmed that the migrations in angular.json (that were getting skipped) make the difference (2x slower ng serve build time)
Benchmarking gives similar results as with angular 11 and markedly better results when I use NG_PERSISTENT_BUILD_CACHE=1
Like @mrucelum our project uses @angular-builders/custom-webpack to specify several packages as externals (legacy code needs the package as well, so don't want to double load them) Is there any chance ng update could do migrations when custom-webpack is in use? Or the ability to specify external packages without using custom-webpack? Thanks everyone for the info that lead me to this solution!
@mrucelum Thanks for all the stats. I'm actually using @angular-builders/custom-webpack:browser
too and for the exact same reason (moment.js size). However I just ran a dozen builds and with or without the custom builder it was taking 38-40 seconds each time. And it definitely did change because it told me to remove the part of the config that was due to the custom builder.
However... as I was writing this though I saw you managed to get them working.....
But, could you confirm that running the migrations did not in fact disable AOT compilation in your angular.json file. Depending upon your exact version of the CLI it's possible to end up disabling it when running migrations (due to a change in what was considered the default). If you in fact did disable AOT then that would explain the much faster compilation. Again though I'm using the same builder and wasn't seeing any noticeable difference between them. (Also version 12.1.0 of the custom builder was just published today - not sure if there were changes or just a version bump)
NG_BUILD_CACHE
is enabled by default, and is mainly used to opt-out all build caching, this supersedesNG_PERSISTENT_BUILD_CACHE
.NG_PERSISTENT_BUILD_CACHE
is disable by default, and can be used to opt-in to cache the entire build on disk, which will make the 2nd build warm. Typically you don't want this on CI since typically the "cache" will be discarded withnode_modules
after every CI run.That being said, this issue is about build times and not memory, hence if you are experiencing memory issues please file a new issue providing all the necessary profiles and/or a reproduction.
Thanks @alan-agius4 for the explanation and sorry you'll probably end up marking this "off topic", but maybe not since it is about NG_PERSISTENT_BUILD_CACHE
and I do care about any build speed improvements I can get since my build does seem slow to me.
I reviewed https://github.com/angular/angular-cli/pull/20756 to confirm I understood and I wasn't taking a corner case that was unexpected. I use NG_BUILD_CACHE
to point to a directory that is external to the node modules and in a location the CI will preserve, and this looks like it's still OK to do based on https://github.com/angular/angular-cli/blob/736a5f89deaca85f487b78aec9ff66d4118ceb6a/packages/angular_devkit/build_angular/src/utils/environment-options.ts#L70-L81 does that mean I should also be able to turn on NG_PERSISTENT_BUILD_CACHE
in order to persist the webpack cache? I noticed this was said to be experimental, but any reason I might not want to turn it on in this context? It looks like the cache key is pretty comprehensive and I would think the serialized build options should probably be good :thinking:
Edit: After thinking about it more I definitely have places I can enable NG_PERSISTENT_BUILD_CACHE
and hopefully it speeds up those paths, so thanks again regardless!
This actually looks to really help a lot for my build time :tada: , but I've found a few errors and I'm reporting them (and fixing the one I can fix simply)
After upgrading from Angular 11 to Angular 12 the build time went up from ~1 second to 22 seconds π€―
@whyboris It doesn't for me:
Is there a particular change I should be making?
@JoostK thank you for testing! I was so frustrated I quit for the day, but thanks to your message I had new hope π
I ran rm -rf node_modules
and npm install
again ~and it looks like I'm back to fast~ π
Build at: 2021-07-07T20:46:38.298Z - Hash: f2c33b8ef37564ec1ef0 - Time: 1713ms
π
~Sorry for the scare~ π
update: π€¦ turns out it still takes ~22 seconds when you just add console.log
in some component
@whyboris Thanks for getting back. Good to hear it's fast again, hopefully it stays that way. If you do run into it again please report back so we can have another look.
@JoostK π€¦ sorry -- the reload was fast because I simply saved the file with no changes ... but when I add console.log
somewhere - thereby changing the file, the compilation takes a long time again:
Build at: 2021-07-07T20:50:32.591Z - Hash: 0a430155980e29d73d08 - Time: 23324ms
π’
It seems to hang on the ... bundles (phase: sealing)...
step
@whyboris Oh, it's just a misconfiguration. In Angular 12 some builder defaults have changed in support of the new production builds by default for ng build
. I am not sure how you updated but I don't see any changes to angular.json
in the pull request; ng update
should have updated it to pin the configuration options to their prior defaults to retain the previous behavior. If I run ng update @angular/cli --migrate-only --from 11 --to 12
then the angular.json
file is indeed updated. Please review the changes as I notice in your case that aot
will be set to false
, which may or may not be desirable.
@JoostK thank you very much for the suggestion!
I went back to my main
branch (before my attempt to upgrade to angular 12) and ran the command you gave:
ng update @angular/cli --migrate-only --from 11 --to 12
It updated my angular.json
file and now the app recompiles quickly after every save π
https://github.com/whyboris/Video-Hub-App/pull/666/files
Thank you π€ π β€οΈ
@whyboris it seems like you set "aot": false
which should be set to true
(if I'm not misstaken)
Just wanted to let you know that I did the migration again the way @DavidBowdoin suggested (remove custom builder before ng update). Aaaand there is no slowdown anymore! π₯³
Not sure what the issue was, maybe it was actually fixed with the newest version of the custom webpack builder (as @simeyla suggested). My angular.json
was not touched by the migration at all (although I removed the custom builder before the migration!), so I guess that was not the problem.
But anyway, I am happy that we can update now! Thanks again everyone! :)
Maybe this can solve this problem https://dev.to/brandontroberts/speeding-up-the-development-serve-after-upgrading-to-angular-v12-5db5
It appears that the root cause of the problem is misconfigurations and not an issue in the Angular CLI.
If you are still experiencing slow production builds please open a new issue with a production.
Removing "emitDecoratorMetadata": true
from tsconfig.json
reduced our build time significantly for production.
Success! I found steps to get good performance when using
@angular-builders/custom-webpack
TLDR; before upgrading angular, remove all traces of
custom-webpack
so the migrations run in full, and then re-installcustom-webpack
Here is what worked for me, starting with an Angular 11 project:
- In angular.json, replaced all traces of
@angular-builders/custom-webpack:browser
with@angular-devkit/build-angular:browser
(and delete thecustomWebpackConfig
block)- Removed
@angular-builders/custom-webpack
from package.json- Deleted
node_modules
andpackage_lock.json
- Ran
npm install
- Ran
ng update @angular/cdk @angular/cli @angular/core
- Added v12 of
@angular-builders/custom-webpack
back into package.json- Ran
npm install
- In angular.json, changed back to
@angular-builders/custom-webpack:browser
and restored thecustomWebpackConfig
block.I confirmed that the migrations in angular.json (that were getting skipped) make the difference (2x slower ng serve build time)
Benchmarking gives similar results as with angular 11 and markedly better results when I use NG_PERSISTENT_BUILD_CACHE=1
Like @mrucelum our project uses @angular-builders/custom-webpack to specify several packages as externals (legacy code needs the package as well, so don't want to double load them) Is there any chance ng update could do migrations when custom-webpack is in use? Or the ability to specify external packages without using custom-webpack? Thanks everyone for the info that lead me to this solution!
This solved my issue! Thanks :)
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.
π Bug report
Command (mark with an
x
)Description
This is v11.2.13:
Verbose log (logging itself causes slowdown, unfortunately...): angular11.txt
This is v12 with yarn.lock and node_modules removed and reinstalled:
Verbose log (logging itself causes slowdown, unfortunately...): angular12.txt
We have a single small *.scss file (overriding some material colors) and it was updated by migration. The application has only one module. I tried removing scss and css from angular.json, but it is still slower than v11.
On average it is 50% slower.
Recorded profile using node 12:
https://link.nithins.me/s2Uca0Ti