Re: [w3ctag/design-reviews] Shared Element Transitions API (Issue #748)

Thank you for working on the explainer, the new one is **vastly** improved and much easier to follow! 👍🏼 

> > It would be nice if there was a way to use SET without the extensive refactoring of having to put the DOM manipulation code in the `transition.prepare()` callback, but something that is easier to make work with feature detection too (e.g. some way to signal the start and end of the transition, while DOM manipulation code remains where it was?)
> 
> The browser needs to capture the 'before' state, which is async. But yeah:
> 
> ```js
> const transition = new SameDocumentTransition();
> await transition.prepare(async () => {
>   await updateTheDOMSomehow();
> });
> ```
> 
> …could have an alternative API like:
> 
> ```js
> const transition = new SameDocumentTransition();
> await transition.captureBeforeState();
> await updateTheDOMSomehow();
> transition.domChanged();
> ```
> 
> The main difference between the two is if `updateTheDOMSomehow` throws. With the split version of the API, `domChanged` won't be called, and now rendering is frozen until some kind of timeout.
> 
> With the callback model, it's more likely that we catch the error, and know to abandon the transition. [WebLocks](https://w3c.github.io/web-locks/#api-lock-manager) use a similar pattern for this reason.
> 

I understand, but the callback model makes this very annoying to use w/ progressive enhancement, and the Web Platform in general is trying to move away from callback-based APIs. 

This is *exactly* the kind of API that would benefit from progressive enhancement, since if it's not available, you just don't get a transition, no big deal. It should be easy to write code that works this way. And lack of this feature is not the only reason people might want to branch and only have the transitions some of the time. E.g. the `prefers-reduced-motion` media query, or a setting to turn off animations are also valid reasons to not have transitions. Branching is still possible with this API, but very cumbersome and boilerplatey:

```js
if (animationsEnabled) { 
   const transition = new SameDocumentTransition();
   await transition.prepare(async () => {
    await updateTheDOMSomehow();
   });
}
else {
 await updateTheDOMSomehow();
}
```

whereas with your alternative API sketch:

```js
const transition = animationChanged ? new SameDocumentTransition() : null;
await transition?.captureBeforeState();
await updateTheDOMSomehow();
transition?.domChanged();
```

Having the rendering be frozen until a timeout could not be such a dealbreaker if the timeout is explicitly specified when creating the transition? After all, DOM manipulation is not a lengthy process (compared to e.g. network requests), so you'd likely need a very small timeout, smaller than the threshold of a lag that is perceptible by humans (60ms). You could also take a signal to abort the operation, [which is good practice anyway](https://w3ctag.github.io/design-principles/#aborting).

> > As an author, I wouldn't even know how to use `transition.prepare()` when using a framework that does the DOM manipulation for me.
> 
> Depends on the framework. I created a React hook to do it, and it's what [http203-playlist.netlify.app](https://http203-playlist.netlify.app/) uses. React has `useLayoutEffect` for hearing about DOM changes before the next render.

I’m sure it's *possible* with every framework, but it's yet another obstacle for authors to figure out which advanced framework feature would do this. E.g. off the top of my head I cannot think of how to reliably do this with Vue, at least not without heuristics and hacks.

-- 
Reply to this email directly or view it on GitHub:
https://github.com/w3ctag/design-reviews/issues/748#issuecomment-1225759756

You are receiving this because you are subscribed to this thread.

Message ID: <w3ctag/design-reviews/issues/748/1225759756@github.com>

Received on Wednesday, 24 August 2022 13:54:16 UTC