Skip to content

Commit 2f59a3a

Browse files
authored
Update two-phase-transition-explainer.md (#13086)
1 parent 90af273 commit 2f59a3a

File tree

1 file changed

+27
-48
lines changed

1 file changed

+27
-48
lines changed

css-view-transitions-2/two-phase-transition-explainer.md

Lines changed: 27 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ See whatwg/html#10616, whatwg/html#11819 and w3c/csswg-drafts#12829.
77
The period between initiating a navigation (e.g. clicking a link) and consuming the content of the next page ([FCP](https://web.dev/articles/fcp)), is a sensitive moment in user experince.
88
It is a point in time where users are very likely to notice delays, jarring moments of frozen display, and abrupt changes to presentation.
99

10-
The core of this being difficult stems from a tradeoff between speed and smoothness.
11-
The new document becomes activate ASAP (in favor of speed), at the moment the headers are received.
12-
However, it cannot render until all of its render-blocking resources and elements are present (in favor of smoothness, preventing FoUCs).
10+
The core of this being difficult stems from a tradeoff between speed and smoothness:
11+
- The new document becomes activate ASAP (in favor of speed), at the moment the headers are received.
12+
- However, it cannot render until all of its render-blocking resources and elements are present (in favor of smoothness, preventing FoUCs).
1313

14-
This "uncanny valley" where the old page is no longer active but the new page cannot render anything is far from being an optimal user experience, and the knobs given for developers to control it are crude and implicit.
14+
So, in the cases where the navigation is not instant, providing some instant animated response might cause an experience that doesn't feel smooth.
15+
16+
This "uncanny valley" where the old page is no longer active but the new page is not rendering any frames is far from being an optimal user experience, and the knobs given for developers to control it are crude and implicit.
1517

1618
# Current knobs
1719

@@ -28,65 +30,42 @@ This would feel smoother but slows down the whole navigation and tweaking it cor
2830
## Timing out render-blocking
2931
This can reduce the jarring time, however it means the transition doesn’t end at the optimal state, and also doesn’t help with making it feel instant.
3032

31-
# Two-phase transition
33+
# Proposed solutions
3234

3335
To make this part of the experience feel more seamless, developers should be able to create a "two-phase page transition".
3436
This transition starts *instantly* after navigation initiation (link click), and continues *smoothly* until the next page is ready to render.
3537
The instant part of the transition can only use information knows to the old page, which could be a skeleton of the new page or something generic of sorts.
3638

37-
To achieve that, there are 3(?) potential avenues
39+
To achieve that, proposing two provide the following:
3840

39-
## Heuristic-based
40-
Allow a subset of animations, e.g. ones that started after the navigation was initiated, to continue until the new page is ready to commit.
41-
This would allow instant reactions to a navigation while not creating the abrupt experience of spotting it prematurely.
41+
## Allowing the author to control the commit scheduling
4242

43-
## Low-level knobs with prerendering support
44-
Currently, deferring the commit, even for same-origin navigation, is not possible. So the browser is responsible for the handover,
45-
not allowing the developer to curate this experience.
43+
```js
44+
// Returns a boolean if the page is prerendered/BFCached and not render-blocked.
45+
navigateEvent.nextDocumentReadyToRender
4646

47-
### Deferring commit
48-
Something like `navigateEvent.waitUntil(promise)` (or `defer` or some such) can let the developer tweak the handover point.
49-
This can of course also be a footgun as it's a simple way to delay navigations, however it's arguably less of a footgun than the current workarounds.
47+
// Allows delaying the commit *without* intercepting as a same-document navigation.
48+
navigateEvent.deferCommit(promise)
49+
```
5050

51-
### Responding to prerender
52-
When prerendering takes place, a more sensible time to hand over the control to the new document is when it is ready to produce a frame (all the render-blocking resources had been discovered).
53-
However, it is not guaranteed that the destination page is prerendered, and there is no hook to know when the new page is ready to render.
51+
Possible usage:
52+
```js
53+
if (!navigateEvent.nextDocumentReadyToRender) {
54+
const transition = document.startViewTransition(show_preview);
55+
navigateEvent.deferCommit(transition.finished);
56+
}
57+
```
5458

55-
A rather low level way to expose this is `navigateEvent.prerender()` which initiates a prerender if that hasn't happened yet, and returns a promise that resolves at that point, and compose it with the `waitUntil` method above.
56-
It is also possible to short-circuit this and somehow declare "please defer commit until prerender", which is perhaps safer than a general-purpose promise-based API.
5759

58-
## Declarative preview transitions
60+
## Allowing animations to defer commit for a short period
5961

60-
The above knobs might be very effective, but might also require expertise to get right.
62+
The above knobs can be very effective, but might also require expertise to get right.
6163

62-
```css
63-
@view-transition {
64-
navigation: preview;
65-
types: skeleton;
66-
}
67-
68-
:active-view-transition-types(skeleton) {
69-
/* style the transition here */
70-
}
71-
```
72-
73-
This is especially expressive together with route-matching:
64+
The likely use case to let an animation continue till the end, so we can perhaps enable this declaratively:
7465

7566
```css
76-
@route (from: movie-list) and (to: movie-details) {
77-
@view-transition {
78-
navigation: preview;
79-
types: skeleton;
80-
}
81-
}
82-
83-
@route (movie-details) {
84-
:active-view-transition-types(skeleton) {
85-
/* style the page as a details page skeleton even if we don't have all the data */
86-
}
67+
::view-transition-group {
68+
animation-navigation-behavior: smooth;
8769
}
8870
```
8971

90-
# Conclusion
91-
Proposing to pursue both the declarative and JS-based approach for completeness (one for ease of use, one for fine-tuning and complete control), and avoid the heuristic approach as it's a bit opaque and implicit.
92-

0 commit comments

Comments
 (0)