Repository navigation
Decreased performance and excessive memory consumption for vitest #32759
Copy link
Copy link
Closed
Labels
angular/build:unit-testarea: @angular/buildarea: performanceIssues related to performanceIssues related to performancefreq1: lowOnly reported by a handful of users who observe it rarelyOnly reported by a handful of users who observe it rarelygemini-triagedLabel noting that an issue has been triaged by geminiLabel noting that an issue has been triaged by geminineeds: investigationRequires some digging to determine if action is neededRequires some digging to determine if action is neededseverity5: regressiontype: bug/fix
Milestone
Description
Which @angular/* package(s) are the source of the bug?
upgrade, Don't known / other
Is this a regression?
Yes
Description
When upgrading from 21.1.6 to 21.2.3, I noticed a noticeable decrease in performance in tests and excessive memory usage.
@angular/* 21.1.6
@angular/* 21.2.3
Complete package example:
{
"name": "frontend",
"version": "0.0.0",
"packageManager": "pnpm@10.32.1",
"browserslist": "> 5%, last 3 Chrome versions, last 3 Firefox version, last 2 Edge major versions, last 2 Safari major versions, last 2 iOS major versions, Firefox ESR",
"scripts": {
"watch": "pnpm store prune && ng build --watch --output-hashing=all",
"start": "ng serve",
"build": "ng build --configuration production",
"test": "ng test --browsers=chromium",
"test-headless": "ng test --browsers=ChromiumHeadless --watch=false",
"test-ci": "ng test --browsers=ChromiumHeadless --coverage --watch=false",
"lint": "ng lint",
"bundle-report": "ng build --configuration production --stats-json && webpack-bundle-analyzer ../public/frontend/stats.json"
},
"private": true,
"dependencies": {
"@angular/animations": "21.2.3",
"@angular/cdk": "21.2.2",
"@angular/common": "21.2.3",
"@angular/compiler": "21.2.3",
"@angular/core": "21.2.3",
"@angular/forms": "21.2.3",
"@angular/platform-browser": "21.2.3",
"@angular/platform-browser-dynamic": "21.2.3",
"@angular/router": "21.2.3",
"@ctrl/ngx-emoji-mart": "9.3.0",
"@fontsource/inter": "5.2.8",
"@fontsource/poppins": "5.2.7",
"@fortawesome/fontawesome-free": "7.2.0",
"@ng-select/ng-select": "21.5.2",
"@ngstack/code-editor": "9.0.0",
"@ngx-translate/core": "17.0.0",
"@popperjs/core": "2.11.8",
"@primeuix/themes": "2.0.3",
"@rails/actioncable": "8.1.200",
"@rails/activestorage": "8.1.200",
"@types/crypto-js": "4.2.2",
"@types/jquery": "3.5.34",
"@types/sanitize-html": "2.16.1",
"@typescript-plus/fast-memoize-decorator": "0.2.1",
"angular-mentions": "1.5.0",
"autolinker": "4.1.5",
"bootstrap": "5.3.8",
"chart.js": "4.5.1",
"chartjs-plugin-datalabels": "2.2.0",
"crypto-js": "4.2.0",
"dayjs": "1.11.19",
"deepmerge-ts": "7.1.5",
"jquery": "3.7.1",
"jspdf": "4.2.0",
"jspdf-autotable": "5.0.7",
"marked": "17.0.4",
"monaco-editor": "0.52.2",
"ngx-color": "10.1.0",
"ngx-cookie-service": "21.1.0",
"ngx-translate-multi-http-loader": "20.0.0",
"object-to-formdata": "4.5.1",
"primeicons": "7.0.0",
"primeng": "21.1.3",
"rxjs": "7.8.2",
"sanitize-html": "2.17.1",
"tslib": "2.8.1",
"typescript": "5.9.3",
"vite": "7.3.1",
"zone.js": "0.16.1"
},
"devDependencies": {
"@angular-devkit/core": "21.2.2",
"@angular-devkit/schematics": "21.2.2",
"@angular-eslint/builder": "21.3.0",
"@angular-eslint/eslint-plugin": "21.3.0",
"@angular-eslint/eslint-plugin-template": "21.3.0",
"@angular-eslint/schematics": "21.3.0",
"@angular-eslint/template-parser": "21.3.0",
"@angular/build": "21.2.2",
"@angular/cli": "21.2.2",
"@angular/compiler-cli": "21.2.3",
"@types/node": "25.4.0",
"@typescript-eslint/eslint-plugin": "8.57.0",
"@typescript-eslint/parser": "8.57.0",
"@typescript-eslint/utils": "8.57.0",
"@vitest/browser-playwright": "4.0.18",
"@vitest/coverage-v8": "4.0.18",
"eslint": "9.39.4",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-jsdoc": "62.8.0",
"eslint-plugin-prefer-arrow": "1.2.3",
"eslint-plugin-unused-imports": "4.4.1",
"postcss-preset-env": "11.2.0",
"vitest": "4.0.18",
"webpack-bundle-analyzer": "5.2.0"
}
}vitest.config.ts
import { defineConfig } from 'vitest/config';
import path from 'path';
export default defineConfig({
resolve: {
alias: { // mocks for sanitize-html lib
fs: path.resolve('./src/vitest-mocks/fs.ts'),
path: path.resolve('./src/vitest-mocks/path.ts'),
qs: path.resolve('./src/vitest-mocks/qs.ts'),
url: path.resolve('./src/vitest-mocks/url.ts'),
'/frontend/browser/assets': path.resolve('./src/assets'),
'/frontend/browser/media': path.resolve('./node_modules/@fortawesome/fontawesome-free/webfonts'),
},
},
test: {
setupFiles: ['./src/vitest.setup.ts'],
fileParallelism: true,
pool: 'threads',
hookTimeout: 15000,
retry: 1
}
});vitest.setup.ts
import { afterEach, beforeEach, vi } from 'vitest';
import { TestBed } from '@angular/core/testing';
// mocks for sanitize-html lib
(globalThis as any).process = { env: {}, cwd: () => '/', };
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.restoreAllMocks();
vi.clearAllTimers();
vi.useRealTimers();
TestBed.resetTestingModule();
});Please provide a link to a minimal reproduction of the bug
No response
Please provide the exception or error you saw
Although locally this could be tolerated, on the CI there are constant memory shortage errors or timeout crashes, even though the previous version worked perfectly.
Caused by: Error: [vitest] Browser connection was closed while running tests. Was the page closed unexpectedly?
❯ WebSocket.<anonymous> node_modules/.pnpm/@vitest+browser@4.0.18_vite@7.3.1_@types+node@25.4.0_sass@1.97.3__vitest@4.0.18/node_modules/@vitest/browser/dist/index.js:3055:16
❯ WebSocket.emit node:events:520:35
Please provide the environment you discovered this bug in (run ng version)
Angular CLI : 21.2.2
Angular : 21.2.3
Node.js : 24.14.0
Package Manager : pnpm 10.32.1
Operating System : linux x64
┌───────────────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├───────────────────────────────────┼───────────────────┼───────────────────┤
│ @angular-devkit/core │ 21.2.2 │ 21.2.2 │
│ @angular-devkit/schematics │ 21.2.2 │ 21.2.2 │
│ @angular/animations │ 21.2.3 │ 21.2.3 │
│ @angular/build │ 21.2.2 │ 21.2.2 │
│ @angular/cdk │ 21.2.2 │ 21.2.2 │
│ @angular/cli │ 21.2.2 │ 21.2.2 │
│ @angular/common │ 21.2.3 │ 21.2.3 │
│ @angular/compiler │ 21.2.3 │ 21.2.3 │
│ @angular/compiler-cli │ 21.2.3 │ 21.2.3 │
│ @angular/core │ 21.2.3 │ 21.2.3 │
│ @angular/forms │ 21.2.3 │ 21.2.3 │
│ @angular/platform-browser │ 21.2.3 │ 21.2.3 │
│ @angular/platform-browser-dynamic │ 21.2.3 │ 21.2.3 │
│ @angular/router │ 21.2.3 │ 21.2.3 │
│ rxjs │ 7.8.2 │ 7.8.2 │
│ typescript │ 5.9.3 │ 5.9.3 │
│ vitest │ 4.0.18 │ 4.0.18 │
│ zone.js │ 0.16.1 │ 0.16.1 │
└───────────────────────────────────┴───────────────────┴───────────────────┘
Anything else?
It may be necessary to add test.config.json or something else that was previously used for karma.
angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"frontend": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
}
},
"architect": {
"build": {
"builder": "@angular/build:application",
"options": {
"outputPath": {
"base": "../public/frontend/"
},
"deployUrl": "/frontend/browser/",
"index": "src/index.html",
"polyfills": ["zone.js"],
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/assets",
{
"glob": "**/*",
"input": "node_modules/monaco-editor/min/vs",
"output": "assets/monaco/vs"
},
{
"glob": "**/*",
"input": "node_modules/@ngstack/code-editor/assets",
"output": "assets/code-editor"
}
],
"allowedCommonJsDependencies": [
"monaco-editor",
"core-js",
"crypto-js",
"dompurify",
"to-px",
"chartjs-plugin-datalabels",
"@typescript-plus/fast-memoize-decorator",
"chart.js",
"html2canvas",
"raf",
"rgbcolor",
"object-to-formdata",
"jspdf",
"jspdf-autotable",
"dayjs",
"dayjs/plugin/utc",
"dayjs/plugin/isBetween",
"sanitize-html"
],
"stylePreprocessorOptions": {
"includePaths": [
"../app/assets/stylesheets"
]
},
"styles": [
"src/styles/app.scss",
"./node_modules/@fontsource/inter/index.css",
"./node_modules/@fontsource/poppins/index.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
"./node_modules/primeicons/primeicons.css"
],
"scripts": [
"./node_modules/jquery/dist/jquery.js",
"./node_modules/@popperjs/core/dist/umd/popper.min.js",
"./node_modules/bootstrap/dist/js/bootstrap.min.js",
"../app/assets/javascripts/shared/dropdown-submenu.js"
],
"aot": false,
"extractLicenses": false,
"sourceMap": true,
"optimization": false,
"namedChunks": true,
"browser": "src/main.ts"
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
},
"fonts": true
},
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"aot": true,
"extractLicenses": true
},
"test": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
}
},
"defaultConfiguration": ""
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"buildTarget": "frontend:build"
},
"configurations": {
"production": {
"buildTarget": "frontend:build:production"
},
"ci": {
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"buildTarget": "frontend:build"
},
"configurations": {
"outputHashing": "all"
}
},
"test": {
"builder": "@angular/build:unit-test",
"options": {
"tsConfig": "src/tsconfig.spec.json",
"runnerConfig": "src/vitest.config.ts",
"buildTarget": "::test"
}
},
"lint": {
"builder": "@angular-eslint/builder:lint",
"options": {
"lintFilePatterns": [
"src/**/*.ts",
"src/**/*.html"
]
}
}
}
}
},
"cli": {
"analytics": false
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
angular/build:unit-testarea: @angular/buildarea: performanceIssues related to performanceIssues related to performancefreq1: lowOnly reported by a handful of users who observe it rarelyOnly reported by a handful of users who observe it rarelygemini-triagedLabel noting that an issue has been triaged by geminiLabel noting that an issue has been triaged by geminineeds: investigationRequires some digging to determine if action is neededRequires some digging to determine if action is neededseverity5: regressiontype: bug/fix
Activity
clydin commentedon Mar 12, 2026
Does pinning the version of only
@angular/buildto21.1.6(leaving all other versions as-is) resolve your issue?Viktor-Ivliev commentedon Mar 12, 2026
Yes, it seems that if you leave “@angular/build”: “21.1.5” (21.1.6 is not available), it shows the expected result.
"@angular/build": "21.2.0" also ok
"@angular/build": "21.2.1" And that's when this problem arises.
Viktor-Ivliev commentedon Mar 17, 2026
I found the cause and the commit, but I don't know enough to understand why it was done this way.
commit: 6ad8608
if I delete this:
661: externalPackages: false,The tests are working as expected
pull: #32635
alan-agius4 commentedon Mar 18, 2026
This should be solved via #32761
Viktor-Ivliev commentedon Mar 18, 2026
Yes, I can confirm that this has been fixed in version 21.2.3. Thank you.
angular-automatic-lock-bot commentedon Apr 18, 2026
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.