Cancel in-progress view transitions on user interaction
Make sure that view transitions don't block user interactions by canceling them when users attempt to interact during the transition period, preventing INP delays.
The View Transitions API creates smooth, app-like transitions between pages. However, cross-document view transitions block rendering between the initial page screenshot and the server response. When users interact during this blocked rendering period, it creates large INP delays.
Performance profiling has shown that view transitions can significantly delay user interactions. The blocked rendering period prevents the browser from responding to user input, creating poor INP scores, especially when users click or tap during navigation transitions.
Chrome's performance best practices recommend canceling view transitions when users interact with the page to prevent these delays. Transitions improve perceived performance with an app-like experience and smooth visual continuity, but they can hurt measured performance (INP) if not implemented carefully.
Anchor to Opt in to cross-document transitions with ,[object Object]Opt in to cross-document transitions with @view-transition
@view-transitionCross-document view transitions don't happen unless both documents opt in with an @view-transition at-rule. Add it to your theme's stylesheet, which every page loads:
assets/base.css
The opt-in is checked per document: the outgoing document's rule gates pageswap, and the incoming document's rule gates pagereveal. Without it, event.viewTransition is always null and the cancellation code in the next section never runs.
Anchor to Cancel transitions on user interactionCancel transitions on user interaction
Add event listeners that cancel the view transition when users interact:
pageswap and pagereveal fire on window, not on the Navigation API's navigation object. Registering them anywhere else silently does nothing, so the transition is never canceled.
pageswap and pagereveal fire on window, not on the Navigation API's navigation object. Registering them anywhere else silently does nothing, so the transition is never canceled.
Use both pointerdown, which captures mouse clicks and touch taps, and keydown, which captures keyboard interactions. Handle pagereveal as well as pageswap: pageswap fires on the outgoing document, but the transition animates on the incoming one.
The { once: true } option makes sure that listeners fire only once per transition, provides automatic cleanup without a manual removeEventListener, and prevents memory leaks.
Anchor to Use view transitions selectivelyUse view transitions selectively
Apply view transitions strategically, not universally.
Good use cases:
- Product card to product page navigation.
- Image gallery browsing.
- Variant image switching.
- Collection to product navigation.
Avoid them for:
- Every navigation. Too aggressive.
- Form submissions.
- Checkout flows.
- Admin and account pages.
- External links.
Anchor to Respect user motion preferencesRespect user motion preferences
Always check for the reduced motion preference:
Anchor to Provide a fallback for unsupported browsersProvide a fallback for unsupported browsers
Support differs between the two kinds of view transition:
| Transition type | Chrome and Edge | Safari | Firefox |
|---|---|---|---|
Cross-document (@view-transition, pageswap, pagereveal) | 126 or later | 18.2 or later | Not supported |
Same-document (document.startViewTransition()) | 111 or later | 18 or later | 144 or later |
Always provide a fallback:
Anchor to Define CSS animationsDefine CSS animations
Anchor to ExamplesExamples
Anchor to Full implementation with cancellationFull implementation with cancellation
Anchor to Conditional transitions based on contextConditional transitions based on context
Don't try to drive a navigation from document.startViewTransition(). That method is same-document only: passing it a navigation callback produces a roughly 250 ms non-interactive cross-fade of the unchanged outgoing page, followed by an ordinary navigation with no transition at all.
To limit cross-document transitions to specific navigations, keep the @view-transition opt-in and skip the transition in pageswap when the destination isn't one you want to animate:
Don't add a .catch() on viewTransition.finished as a navigation fallback. finished fulfills even when the transition is skipped, so the fallback is dead code. Only viewTransition.ready rejects on a skipped transition.
Don't add a .catch() on viewTransition.finished as a navigation fallback. finished fulfills even when the transition is skipped, so the fallback is dead code. Only viewTransition.ready rejects on a skipped transition.
Anchor to CSS for view transitionsCSS for view transitions
Anchor to Common issue: view transitions blocking interactionsCommon issue: view transitions blocking interactions
Problem: The transition blocks the user from interacting until it completes. Solution: Implement cancellation on interaction, as shown in the Cancel transitions on user interaction section.
Problem: Overuse causes motion sickness and slows navigation. Solution: Use view transitions selectively, only for product cards and galleries.
Anchor to Common issue: ignoring the reduced motion preferenceCommon issue: ignoring the reduced motion preference
Problem: Transitions show for users who prefer less motion. Solution: Check the prefers-reduced-motion media query.
Anchor to TestingTesting
- Enable view transitions and profile navigation interactions in the Chrome DevTools Performance panel.
- Interact during a transition (click, tap, or keyboard) and measure INP before and after adding the cancellation implementation.
- Test navigation from a collection page to a product page during a transition.
- Test multiple quick clicks during a transition.
- Test keyboard navigation and touch interactions on mobile during a transition.
- Test with a slow network using network throttling.
- Compare with and without view transitions enabled.
- Log transitions for debugging:
Anchor to ReferencesReferences
- View Transitions API on MDN.
@view-transitionon MDN.Window: pageswapevent on MDN.Window: pagerevealevent on MDN.ViewTransition.skipTransition()on MDN.- View Transitions examples (live demo).
prefers-reduced-motion(accessibility consideration).- Understanding INP
- Optimize event handlers for responsiveness