Anthropic made claude.ai typeable much sooner: the p75 time to a typeable page on a fresh load went from 3.1 seconds to 0.55. One of the changes baked a static composer into the HTML, so people can type while React is still initializing, and React then paints on top of that HTML copy.

The same gap in Angular

An Angular app rendered on the server has the same window. The HTML arrives and looks interactive, but event listeners are not attached until hydration completes. A click in that window has nothing to handle it.

Event replay

Event replay captures those early interactions and replays them once hydration is done. It is enabled alongside incremental hydration. If you opt out of incremental hydration, you can still turn it on yourself:

import {
  provideClientHydration,
  withEventReplay,
  withNoIncrementalHydration,
} from '@angular/platform-browser';

bootstrapApplication(App, {
  providers: [provideClientHydration(withNoIncrementalHydration(), withEventReplay())],
});

Event replay does not make hydration faster. It makes the wait harmless for the clicks that happen during it, which is often what users notice first.

One more thing to measure

The same claude.ai write-up found that 31% of page loads moved something after the page was usable, without any user interaction. In an SSR app, that is worth checking too: content that shifts as the app takes over is the next thing users trip over once their clicks no longer get lost.

Sources

I post short notes like this on LinkedIn.

Need help with this?

Notebook sketch: a timeline from HTML arrives to user clicks to app hydrates. Without event replay the click lands too early and is lost; with event replay it is recorded, then replayed. Below, provideClientHydration(withEventReplay()), on by default with incremental hydration.

Have an Angular app that needs a senior hand?

Tell me about your app and what is slowing your team down. We go through it on a call and you leave with concrete next steps.