@@ -318,30 +318,46 @@ export class AngularServerApp {
318318 SERVER_CONTEXT_VALUE [ renderMode ] ,
319319 ) ;
320320
321- if ( inlineCriticalCss ) {
322- // Optionally inline critical CSS.
323- this . inlineCriticalCssProcessor ??= new InlineCriticalCssProcessor ( ( path : string ) => {
324- const fileName = path . split ( '/' ) . pop ( ) ?? path ;
325-
326- return this . assets . getServerAsset ( fileName ) . text ( ) ;
327- } ) ;
321+ if ( ! inlineCriticalCss ) {
322+ return new Response ( html , responseInit ) ;
323+ }
328324
329- if ( renderMode === RenderMode . Server ) {
330- // Only cache if we are running in SSR Mode.
331- const cacheKey = await sha256 ( html ) ;
332- let htmlWithCriticalCss = this . criticalCssLRUCache . get ( cacheKey ) ;
333- if ( htmlWithCriticalCss === undefined ) {
334- htmlWithCriticalCss = await this . inlineCriticalCssProcessor . process ( html ) ;
335- this . criticalCssLRUCache . put ( cacheKey , htmlWithCriticalCss ) ;
325+ this . inlineCriticalCssProcessor ??= new InlineCriticalCssProcessor ( ( path : string ) => {
326+ const fileName = path . split ( '/' ) . pop ( ) ?? path ;
327+
328+ return this . assets . getServerAsset ( fileName ) . text ( ) ;
329+ } ) ;
330+
331+ const { inlineCriticalCssProcessor, criticalCssLRUCache } = this ;
332+
333+ // Use a stream to send the response before inlining critical CSS, improving performance via header flushing.
334+ const stream = new ReadableStream ( {
335+ async start ( controller ) {
336+ let htmlWithCriticalCss ;
337+
338+ try {
339+ if ( renderMode === RenderMode . Server ) {
340+ const cacheKey = await sha256 ( html ) ;
341+ htmlWithCriticalCss = criticalCssLRUCache . get ( cacheKey ) ;
342+ if ( ! htmlWithCriticalCss ) {
343+ htmlWithCriticalCss = await inlineCriticalCssProcessor . process ( html ) ;
344+ criticalCssLRUCache . put ( cacheKey , htmlWithCriticalCss ) ;
345+ }
346+ } else {
347+ htmlWithCriticalCss = await inlineCriticalCssProcessor . process ( html ) ;
348+ }
349+ } catch ( error ) {
350+ // eslint-disable-next-line no-console
351+ console . error ( `An error occurred while inlining critical CSS for: ${ url } .` , error ) ;
336352 }
337353
338- html = htmlWithCriticalCss ;
339- } else {
340- html = await this . inlineCriticalCssProcessor . process ( html ) ;
341- }
342- }
354+ controller . enqueue ( htmlWithCriticalCss ?? html ) ;
355+
356+ controller . close ( ) ;
357+ } ,
358+ } ) ;
343359
344- return new Response ( html , responseInit ) ;
360+ return new Response ( stream , responseInit ) ;
345361 }
346362
347363 /**
0 commit comments