perf(@angular/build): share sass directory and resolution caches across stylesheets - #34041
Conversation
There was a problem hiding this comment.
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.
956ccc0 to
2361ada
Compare
…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%.
…es across stylesheets
cf733f1 to
2119fd6
Compare
…es across stylesheets
|
This PR was merged into the repository. The changes were merged into the following branches:
|
…tylesheets Port angular/angular-cli#34041 to ng-packagr. 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. 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() or clearCache(). - Hoist resolutionCache and packageRootCache to module-scoped caches in sass-language.ts, clearing them via resetSassWorkerPoolCaches() during shutdownSassWorkerPool() or when invalidating component stylesheets. - Contextualize relative import resolution cache keys and package root cache keys using the containing URL to preserve correctness while allowing package specifiers to resolve once across all stylesheets.
…tylesheets Port angular/angular-cli#34041 to ng-packagr. 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. 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() or clearCache(). - Hoist resolutionCache and packageRootCache to module-scoped caches in sass-language.ts, clearing them via resetSassWorkerPoolCaches() during shutdownSassWorkerPool() or when invalidating component stylesheets. - Contextualize relative import resolution cache keys and package root cache keys using the containing URL to preserve correctness while allowing package specifiers to resolve once across all stylesheets.
Previously, Sass resolution caches (
resolutionCacheandpackageRootCache) insass-language.tsand the filesystem directory entry cache (directoryCache) insass-service.tswere 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/materialor deep-imported@material/*packages), rebasing importers repeatedly invoked synchronousfs.readdirSyncacross the same node module package directories, and re-executed esbuild resolution calls.To eliminate redundant disk I/O and resolution overhead:
directoryCacheto an instance property ofSassCompiler, persisting directory listings across compile calls and clearing them upon compiler shutdown inclose().resolutionCacheandpackageRootCacheto module-scoped caches insass-language.ts, clearing them duringshutdownSassWorkerPool().In benchmarks on an application with 50 component SCSS stylesheets importing
@angular/material, synchronousfs.readdirSynccalls dropped from 2,900 to 205 (-92.9%),build.resolvecalls dropped from 100 to 2 (-98.0%), and compilation time improved by up to 26.4%.