Skip to content

perf(@angular/ssr): pre-compile critical CSS plans at build time - #33992

Merged
alan-agius4 merged 2 commits into
angular:mainfrom
alan-agius4:css-inline-rework
Sep 3, 2026
Merged

perf(@angular/ssr): pre-compile critical CSS plans at build time#33992
alan-agius4 merged 2 commits into
angular:mainfrom
alan-agius4:css-inline-rework

Conversation

@alan-agius4

@alan-agius4 alan-agius4 commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Pre-compiles stylesheet critical CSS plans during build time and embeds them into the server application manifest instead of performing full CSS and HTML parsing dynamically at runtime on every SSR request.

Changes

  • Build time: In @angular/build, uses Beasties compiler (compileSheet and encodePlan) to pre-compile stylesheet plans and embeds criticalCssPlans and any template nonce into the server application manifest.
  • Runtime: In @angular/ssr, initializes Beasties runtime processor with criticalCssPlans, enabling fast, single-pass critical CSS inlining for response handling and streaming without runtime LRU cache and SHA-256 hashing.
  • Cleanup: Removes @angular/ssr internal InlineCriticalCssProcessor, LRUCache, and crypto.ts utilities, as well as the bundled third-party Beasties distribution in favor of the upstream package.
  • Testing: Updates setAngularAppTestingManifest to accept stylesheet CSS records and compile plans internally.

Depends on #34014.

@angular-robot angular-robot Bot added area: build & ci Related the build and CI infrastructure of the project area: performance Issues related to performance area: @angular/ssr labels Sep 2, 2026
@alan-agius4
alan-agius4 force-pushed the css-inline-rework branch 5 times, most recently from 31f8133 to 4eb1d31 Compare September 2, 2026 14:54
@alan-agius4 alan-agius4 added the target: minor This PR is targeted for the next minor release label Sep 2, 2026
@alan-agius4
alan-agius4 force-pushed the css-inline-rework branch 4 times, most recently from 5c6aa18 to bf1c206 Compare September 3, 2026 14:41
Previously, critical CSS inlining in `@angular/ssr` was executed dynamically at runtime
by parsing HTML and stylesheets on each request (or caching processed HTML in an in-memory
LRU cache keyed by SHA-256 content hashes). This incurred significant CPU and latency
overhead during request processing and precluded efficient stream processing.

This commit updates the critical CSS workflow to pre-compile stylesheet plans during the
build step via Beasties' compiler (`compileSheet` and `encodePlan`). These compact plans
are stored in the server application manifest (`criticalCssPlans`) along with any CSP
nonce.

At runtime, `AngularServerApp` initializes Beasties' runtime processor with the
pre-compiled plans, allowing fast single-pass string and stream processing without
re-parsing stylesheets, calculating content hashes, or maintaining a runtime LRU cache.
Consequently, `InlineCriticalCssProcessor`, `LRUCache`, and `crypto.ts` utility classes
have been removed from `@angular/ssr`.
@alan-agius4
alan-agius4 requested review from clydin and dgp1130 and removed request for dgp1130 September 3, 2026 15:16
@alan-agius4 alan-agius4 added the action: review The PR is still awaiting reviews from at least one requested reviewer label Sep 3, 2026
@alan-agius4
alan-agius4 marked this pull request as ready for review September 3, 2026 15:16

@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 replaces the internal bundled version of the beasties library with the official npm package dependency, removing custom implementations of the critical CSS processor and LRU cache in favor of beasties/runtime. It also introduces build-time pre-compilation of critical CSS plans and nonce extraction into the server application manifest. The review feedback highlights a high-severity issue where an error during CSS inlining could abort streaming responses mid-flight, a bug in the regex used for extracting unquoted nonces, and an opportunity to simplify a dynamic import now that the module resolution is set to bundler.

Comment thread packages/angular/ssr/src/app.ts
Comment thread packages/angular/build/src/utils/server-rendering/manifest.ts Outdated
Comment thread packages/angular/build/src/utils/server-rendering/manifest.ts
@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Sep 3, 2026
@alan-agius4
alan-agius4 merged commit 23e3d44 into angular:main Sep 3, 2026
40 checks passed
@alan-agius4

Copy link
Copy Markdown
Collaborator Author

This PR was merged into the repository. The changes were merged into the following branches:

@alan-agius4
alan-agius4 deleted the css-inline-rework branch September 3, 2026 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: merge The PR is ready for merge by the caretaker area: @angular/ssr area: build & ci Related the build and CI infrastructure of the project 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.

2 participants