Share
Embed
Angular SSR, Defer & Incremental Hydration
This presentation by Alexander Thalhammer explains advanced initial load performance optimization strategies with Angular NG 19, focusing on server-side rendering (SSR), static site generation (SSG), deferrable views using the @defer syntax, and incremental hydration. It demonstrates how these techniques can reduce initial load times and improve user experience by pre-rendering content on the server, deferring the loading of non-critical JavaScript, and rehydrating components on demand, all supported by practical labs and best practices.
Alex T
March 20, 2025
Transcript
58 slides
-
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer SSR, SSG,
Deferrable Views and Incremental Hydration in NG 19 Alexander Thalhammer, ANGULARarchitects.io Git: https://github.com/L-X-T/ssr-ih-ng19-days https://LXT.dev https://LXT.dev -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 2 Why
performance optimization? UX Ranking Traffic Bounce- Rate Conversions -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 3 Why
server-side rendering? improve Initial Load save ressources -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 4 Why
server-side rendering? https://www.acldigital.com/blogs/zero-hydration-qwik-future-web -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 6 Challenges
server login dynamic content translation federation -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 9 •
Alexander Thalhammer from Graz, Austria (est. 1983) • Angular Software Tree GmbH (est. 2019) • Web Dev for 24 years • Since 2017 Angular Dev • Since 2021 Angular Evangelist, Coach & Consultant • Member of the Angular Architects Hi, it's me → @LX_T -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 10 @LX_T
→ favorite topics Performance Accessibility Best Practices -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 11 1)
Server-Side Rendering (SSR) 2) Prerendering during build (SSG) 3) Hydration (NG >= 16) 4) Event Replay (NG >= 18) 5) Hybrid Rendering (NG => 19) 6) Deferrable Views (NG >= 17) 7) Incremental Hydration (NG >= 19) Agenda -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 12 Labs
Audit @defer Incremental Hydration [repository] https://github.com/L-X-T/ssr-ih-ng19-days -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 14 •
Lazy Loading === Defer Loading • Lazy Loading for router-based lazy loading using loadChildren() / loadComponent() • Defer Loading for template-based lazy loading using @defer • Hydration → attach JS (event handlers) to static HTML • client-side rendering SR, server-side rendering, static site generation • above-the-fold First things first: terminology -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 15 •
measure your Angular apps initial load performance • make improvements measurable • how to measure? First things first: Measure performance -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 16 •
ng b(uild) • npm i - g serve • serve dist/[appName]/browser -s • open http://localhost:3000 in chrome and run Lighthouse (DevTools) test Test Angular App with Google Lighthouse -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 17 Lab:
Measure performance with Lighthouse https://github.com/L-X-T/ssr-ih-ng19-days/blob/main/labs/01-audit.md -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 18 •
replaces Universal package • community solution • new per default part of: ng new • or existing: ng add @angular/ssr 1) SSR @angular/ssr (v17) -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 19 •
(static) HTML is rendered on the server and then downloaded by client • like classic web pages • better performance 1) SSR – Essentials -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 20 •
when trying to rank in search enginges, implement the Meta Tags 1) SSR – SEO Considerations -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 21 •
valid HTML required (anyway good practice ☺) • certain Browser features not available, e.g. • document, window, localStorage, sessionStorage • private readonly document = inject(DOCUMENT); • private readonly platform = inject(PLATFORM_ID); 1) SSR – Common Pitfalls -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 22 1)
SSR – platfrom check -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 23 1)
SSR – Browser only render hooks • afterNextRender() • afterRender() → might be renamed into afterEachRender() -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 24 1)
SSR – caution with ng serve in v19 • disable hot module reloading • ng serve –no-hmr -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 25 DEMO
SSR ng serve --no-hmr https://github.com/L-X-T/ssr-ih-ng19-days -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 26 •
on-demand-rendering on server needs time & ressources • solution: Prerendering (SSG) • Static content can be pre-rendered at build time • cons • not usable for dynamic content • delays build time 2) Prerendering during building (SSG) • pros • very fast initial load time • no node.js/Express server needed -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 27 DEMO
SSG ng build https://github.com/L-X-T/ssr-ih-ng19-days -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 28 •
now called full-application hydration • interactivity (JS) is attached in client to static HTML from server • specifically, all Angular event handlers (click)="doSth()" are attached 3) non-destructive (v16) -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 29 •
until Angular 16 SSR HTML was thrown away and replaced with CSR HTML • resulted in flickering during initial loading • hydration avoids layout shifts (bad UX) • only with this feature is SSR in Angular usable (from v16 onward) 3) why non-destructive? -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 30 •
some components (e.g. external libraries) are not compatible • hydration can be disabled for individual components using • or via host binding 3) Hydration Trouble Shooting -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 31 •
user events are captured and fired again after hydration • this enables user interactions during the initial loading of the app 4) Event Replay (v18) -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 32 •
JSAction (a mini-library from Google’s Wiz Framework) intercepts all events on the body element and fires them again after the initial load 4) Event Replay – Details -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 33 •
from NG 19 onwards, we can choose the mode for each route: • RenderMode.Prerender (SSG) for static content • RenderMode.Server (SSR) for dynamic content • RenderMode.Client (CSR) for user-dependent content 5) Hyrbid Rendering (v19) -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 34 •
additionally, redirects or error pages can be delivered 5) Hyrbid Rendering – 301 & 404 -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 35 DEMO
Hybrid Rendering https://github.com/jeanmeche/ssr-v19 -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 37 NgModules
– Common Issue AppModule … Root Module Feature Module(s) Shared Module SharedModule -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 38 Digression
– Angular Migrations (mandatory!) standalone control flow build w/ esbuild & vite lazy-loaded routes signal inputs & queries cleanup imports & self-closing tags -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 39 Angular
Docs – Migration https://angular.dev/reference/migrations -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 40 •
only works with standalone components • alternative to router-based Lazy Loading in Angular • to reduce initial load (size and time) → improve performance • without own route • very good DX compared to previous solutions with ViewContainerRef 6) Deferrable Views with @defer (v17) -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 41 •
widgets that are used on multiple routes • lazy loading large 3rd-party dependencies (e.g., charts, tables, etc.) • forces CSR → combine with SSR for user-dependent content (e.g., price) • not suited for above-the-fold content (initially only placeholder is shown) 6) Deferrable Views – Examples -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 42 •
triggers (lazy) loading of the component • e.g. on viewport (like ngOptimizedImage) 6) Deferrable Views – Trigger Intro -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 43 •
on • immediate • idle (default) • viewport (like ngOptimizedImage) • hover (mouseover & focusin) • interaction (click & keydown) • timer(4200ms) (use case → demo) 6) Deferrable Views – Trigger Details • when • boolean symbol or • Signal<boolean> or • function • both are one-way ticket • combination possible -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 44 •
with prefetch, the deferred JavaScript can be preloaded • similar to the PreloadingStrategy used in router-based lazy loading • this speeds up the loading process when the @defer trigger is activated 6) Deferrable Views – Prefetch -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 45 •
@placeholder • @loading • @error 6) Deferrable Views – Placeholder & Loading -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 46 •
be careful with nested @defer blocks • they should use different triggers • be cautious when @defer is triggered above-the-fold and during the initial load • no layout shifts should occur (poor UX) 6) Deferrable Views – Best Practices -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 47 •
in combination with SSR, the @placeholder is rendered on the server • or nothing if no @placeholder is provided • only on the client the @defer blocks' main content is rendered • thereby enforcing client-side rendering • only with Incremental Hydration main content pre-rendered on the server 6) Deferrable Views – Combination with SSR -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 48 Lab:
@defer https://github.com/L-X-T/ssr-ih-ng19-days/blob/main/labs/02-defer.md -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 49 7)
Incremental Hydration (v19) incremental hydration -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 50 •
based upon Hydration, @defer and Event Replay • enables even better intial load experience, because • less JavaScript is shipped → partial lazy loading of JS on demand • @defer blocks now can also be used above-the-fold, because • the main content (instead of @placeholder) is rendered on the server 7) Incremental Hydration (v19) -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 51 •
same triggers like @defer • on (immediate, idle, viewport, hover, interaction) • when (boolean symbol, Signal<boolean> or funktion) • never (for static content without interactivity) 7) Incremental Hydration – Trigger -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 52 •
Above-the-fold content (now usable) • Dynamic below-the-fold ccntent • Products in a online shop • Forms and Actions • Interactive Tables 7) Incremental Hydration – Scenarios -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 53 Lab:
Incremental Hydration https://github.com/L-X-T/ssr-ih-ng19-days/blob/main/labs/03-incremental-hydration.md -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 54 1)
Faster Angular Apps (LCP & INP) 2) Better UX 3) Everybody happy ☺ Recap – Why SSR & Incremental Hydration -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 55 1)
Build Application with Angular 2) Server-Side Rendering with node.js 3) Transfer to / Load by client (HTTP) 4) Browser Parsing & Rendering 5) Full app Hydration 6) Full app Event Replay if(@defer) Load, Parse, Render, Hydrate & Event Replay if(hydrate) Load, Parse, Hydrate & Event Replay Recap – Hydration steps -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 56 Conclusion
improve you initial load with SSR SSG (prerender) static content @defer for components below-the-fold Incremental Hydration for above-the-fold try it & play with it! -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 57 •
angular.dev/guide/performance - official SSR docs • angular.dev/guide/incremental-hydration - official IH docs • youtube.com/watch?v=v5KTJGEYLsM – IH intro by Jessica Janiuk • angulararchitects.io/blog/complete-guide-for-server-side-rendering-ssr-in-angular/ • angulararchitects.io/training/angular-performance-optimization-workshop/ Ressources -
• Textmasterformat bearbeiten • Zweite Ebene Alexander Thalhammer 58 [X]
@LX_T [web] https://lxt.dev Thank you for the attention Slides & Source Remote Workshops and Consulting https://angulararchitects.io Angular Updates