Skip to content

perf(@angular/build): share sass directory and resolution caches across stylesheets - #34041

Open
alan-agius4 wants to merge 1 commit into
angular:mainfrom
alan-agius4:perf/sass-caching
Open

perf(@angular/build): share sass directory and resolution caches across stylesheets#34041
alan-agius4 wants to merge 1 commit into
angular:mainfrom
alan-agius4:perf/sass-caching

Conversation

@alan-agius4

Copy link
Copy Markdown
Collaborator

Previously, Sass resolution caches (resolutionCache and packageRootCache) in sass-language.ts and the filesystem directory entry cache (directoryCache) in sass-service.ts were created anew for every individual stylesheet compilation request.

When compiling applications that use component styles importing shared design tokens or library stylesheets (such as @angular/material or deep-imported @material/* packages), rebasing importers repeatedly invoked synchronous fs.readdirSync across the same node module package directories, and re-executed esbuild resolution calls.

To eliminate redundant disk I/O and resolution overhead:

  • Hoist directoryCache to an instance property of SassCompiler, persisting directory listings across compile calls and clearing them upon compiler shutdown in close().
  • Hoist resolutionCache and packageRootCache to module-scoped caches in sass-language.ts, clearing them during shutdownSassWorkerPool().
  • Contextualize relative import resolution cache keys using the containing URL to preserve correctness while allowing package specifiers to resolve once across all stylesheets.

In benchmarks on an application with 50 component SCSS stylesheets importing @angular/material, synchronous fs.readdirSync calls dropped from 2,900 to 205 (-92.9%), build.resolve calls dropped from 100 to 2 (-98.0%), and compilation time improved by up to 26.4%.

@angular-robot angular-robot Bot added area: performance Issues related to performance area: @angular/build labels Sep 8, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces persistent caching for Sass compilation to improve performance. It shares the resolution and package root caches across compile requests in sass-language.ts and moves the directory cache in SassCompiler to a class-level property. The review feedback identifies a critical correctness issue where relative imports not starting with . are incorrectly cached globally, which can be resolved by qualifying all non-pkg: imports with the containing URL. Additionally, it is recommended to expose a public clearCache() method on SassCompiler to allow clearing the directory cache during rebuilds.

Comment thread packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts Outdated
Comment thread packages/angular/build/src/tools/sass/sass-service.ts
@alan-agius4 alan-agius4 added the target: minor This PR is targeted for the next minor release label Sep 8, 2026
…ss stylesheets

Previously, Sass resolution caches (resolutionCache and packageRootCache) in sass-language.ts and the filesystem directory entry cache (directoryCache) in sass-service.ts were created anew for every individual stylesheet compilation request.

When compiling applications that use component styles importing shared design tokens or library stylesheets (such as @angular/material or deep-imported @material/* packages), rebasing importers repeatedly invoked synchronous fs.readdirSync across the same node module package directories, and re-executed esbuild resolution calls.

To eliminate redundant disk I/O and resolution overhead:
- Hoist directoryCache to an instance property of SassCompiler, persisting directory listings across compile calls and clearing them upon compiler shutdown in close().
- Hoist resolutionCache and packageRootCache to module-scoped caches in sass-language.ts, clearing them during shutdownSassWorkerPool().
- Contextualize relative import resolution cache keys using the containing URL to preserve correctness while allowing package specifiers to resolve once across all stylesheets.

In benchmarks on an application with 50 component SCSS stylesheets importing @angular/material, synchronous fs.readdirSync calls dropped from 2,900 to 205 (-92.9%), build.resolve calls dropped from 100 to 2 (-98.0%), and compilation time improved by up to 26.4%.
@alan-agius4
alan-agius4 requested a review from clydin September 8, 2026 14:56
@alan-agius4 alan-agius4 added the action: review The PR is still awaiting reviews from at least one requested reviewer label Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: review The PR is still awaiting reviews from at least one requested reviewer area: @angular/build area: performance Issues related to performance target: minor This PR is targeted for the next minor release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant