WICG / navigation-api

The new navigation API provides a new interface for navigations and session history, with a focus on single-page application navigations.
https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigation-api
487 stars 26 forks source link

Replace transitionWhile()/canTransition with intercept()/canIntercept #235

Closed domenic closed 2 years ago

domenic commented 2 years ago

Fixes #230. Mini-explainer:

The "navigate" event provided by the navigation API has a method on its NavigateEvent instance, event.transitionWhile(promise, options). This method would intercept the navigation, convert it into a same-document navigation, and then use the provided promise to signal to the browser and to other parts of the web application that we were in a transitional phase while the new navigation finishes up.

However, the signature of transitionWhile(promise) worked poorly in practice. The most important reason is the common coding pattern of:

event.transitionWhile((async () => {
  doSyncStuff();
  await doAsyncStuff();
})());

i.e., the common pattern of generating a promise via an immediately-invoked async function. The problem with this pattern is that it's equivalent to

doSyncStuff();
event.transitionWhile((async () => {
  await doAsyncStuff();
})());

This means some portion of your "navigation handling code" would run, before the navigate event had finished firing and the URL/entry had been updated.

We know of at least two bad examples of this:

Our solution is to replace transitionWhile(promise, options) with intercept({ handler, ...options }). Essentially, we are replacing the idea of you passing a promise---which people would often generate with an async function---with the idea of you passing an async function directly. Then, the user agent can be sure to schedule the entirety of the async function after the navigate event has finished firing, and the URL/entry updated. This avoids the above problems.

This particular API shape has other minor benefits:


Preview | Diff

jakearchibald commented 2 years ago

I know I caused a lot of trouble by whinging about this late in the process, but I'm really grateful that this change happened. I'm giving a talk on this later, and this API makes it so much easier to explain (especially as I'm talking about page transitions in the same talk).