#748: View Transitions API

Visit on Github.

Opened Jun 16, 2022

Wotcher TAG!

I'm requesting a TAG review of View Transitions.

View Transitions is a proposal for a new web API that allows a simple set of transition animations in both Single-Page Applications (SPAs) and Multi-Page Applications (MPAs).

The inspiration for this feature are transitions similar to the ones listed in the Material Design Principles. The intent is to support transitions similar to Android Activity Transitions.

  • Explainer¹ (minimally containing user needs and example code): explainer
  • Specification URL: Draft spec
  • Tests: WPTs. These will be merged upstream when shipping the feature.
  • User research: N/A
  • Security and Privacy self-review²: questionnaire
  • GitHub repo (if you prefer feedback filed there): WICG repo
  • Primary contacts (and their relationship to the specification):
    • Khushal Sagar (@khushalsagar), Google
    • Vladimir Levin (@vmpstr), Google
    • Tab Atkins (@tabatkinds), Google
  • Organization(s)/project(s) driving the specification: Google
  • Key pieces of existing multi-stakeholder review or discussion of this specification:
  • External status/issue trackers for this specification (publicly visible, e.g. Chrome Status): Chrome Status

Further details:

  • [ X] I have reviewed the TAG's Web Platform Design Principles
  • Relevant time constraints or deadlines: N/A
  • The group where the work on this specification is currently being done: WICG
  • The group where standardization of this work is intended to be done (if current group is a community group or other incubation venue): CSSWG
  • Major unresolved issues with or opposition to this specification: N/A
  • This work is being funded by: Google

We'd prefer the TAG provide feedback as (please delete all but the desired option):

☂️ open a single issue in our GitHub repo for the entire review

Discussions

Discussed Jul 1, 2022 (See Github)

Lea: this is substantial. Defer to the f2f?

Dan: I set it for next week.

Discussed Aug 1, 2022 (See Github)

brief discussions

Lea: totally new thing... Work happened to improve it. Looked at explainer - well written - we need to go through it.

Peter: I had a brief look.

Tess: also a thing where there have been lots of attempts in the broader space... to what extent are people aware of this familar with those prior attempts...?

put on the agenda for next week

Peter: homework assignment to read through the explainer.

Discussed Aug 1, 2022 (See Github)

...reviewing explainer...

Dan: is this designed in the right way to enable the UX they want to enable. Inevitably we'll have to get into the question of could there be leakage between two different documents in a way that violates privacy or breaks web security.

Dan: noting that this is purely for same-origin transitions and that cross-origin transitions aren't part of the proposal; additionally there are some noted security considerations.

Dan: reviewing the s&p questionnaire responses; looks good as long as it's confined to same origin. Cross-origin will be trickier and will require more thought. We should note that in the review response.

Dan: note other things to take into account if it was cross-origin, so we should note our response is purely in the context of same-origin

Lea: from an API point of view, do you understand how to use it? as an author?

Peter: I don't entirely follow the design

Lea: it's a very thoroughly written explainer... but I don't get it.

Hadley: doesn't have use cases from a user flow perspective

Lea: I think there are many use cases, but I don't understand how to use this to get them to work

Rossen: if you look at the default setup and how it's used in the customisation of an animation I think it's pretty easy to follow. You set up your animation as a property bag that you transition through, then execute it in the context of the new document. Querstion - if you have a log running animation, not sure what type of effect would that have? Your property value is going to be kept alive for the duration fo that animation, as stated in the section for ending the transition. Other than that it sems straightforwad.

Lea: how low level is it? Right now with CSS transitions and animations it's a significant problem that authors cannot animnate between auto and other numbers. If a container has auto dimensions in both documents can you still animate between them?

Rossen: nothing changing on the basis of this of what values are animateable. Exactly the same behaviour as any other in-page animation or transition. Intent is not to extend that. That is one of the non-goals. Not precluding that in the future.

Lea: if you use this by default you get a crossfade, and everything else is a customisation from there? That's cool.

Dan: Hadley, you mentioned you didn't think there's enough initial discussion of use cases?

Hadley: I understood they're trying to make transitions more seamless?

Rossen: the use cases are well articulated. Preamble.. different design language currently being useed in native platforms and how they benefit native applications in their transitions

... author of one page wants to fade their content out... keeping the load going in the new destination and then can kick off the animation and give you a nice transition.

Hadley: that's helpful - addresses my concerns...

Lea: if you're using an app on a phone for ex, you get these transitions - but you don't get these on the web in multi-page web applications so this can bridge that gap...

Dan: or people are forced to create SPAs in order to achieve this effect. Ideally they'd be multi-page, which would fit bitter with web architecture. Individually addressable pages. One thing that aids my understanding of it is that it's sprinkled with videos and images which help to reinforce what they're talking about

Lea: still some questions- the explainer mentions you use a prepare() method with a callback. In the example it updates the dom somehow.

Rossen: This is the time when you have the ability to handshake between the two states - and add additional state into your new environment. What they're doing: they are highlighting the fact you can use the same for both - for in-pave and between-page? Happy to look further.

Dan: I'm generally concerned about complexity, although maybe this is inevitable

Lea: I don't know..

Rossen: every time you try to create a pattern that's intended to transfer a state from one navigation to another - privacy securty, etc... - and make it execute into that new context you're going to have a set of complexity... Is it the simplest way of doing it? Not sure. On the surface when I read the explainer it didn't seem overly complex compared to the goals they're trying to achive.

Lea: if we feel it would be useful Jake could join a call...

Rossen: ...could be helpful...

Lea: hesitant to say let's move forward because I don't feel I understand it well enough. But also the use cases are very important and need solving.

Rossen: We want to do a good job of proving good reviews.... We could say we had a good initial discussion where we validated the use cases but for examople I haven't validated what it means for accessibility - certain live regions on the new document that may be covered with other content. Other one is the privacy - which is mitigated by it being same origin. Next logical step is how do we make it work for cross origin. Don't want it to be carried forward to cross-origin. They already have some experimental implementation. My suggestion would be to load up one of their examples and get a feel for it.

Dan: Agree with Rossen. I don't think we need to bring Jake onto a call given our schedule. We should be able to accomplish some additional work with him or the requestors async. Would it be possible Lea to leave some comments on the thread asking the questions that you have? One thing that does strike me [... misse d a bit...] there's some more example text in the spec, but it's not exactly what I'm talking about, maybe that doesn't exist

Peter: I remember a tweet from Jake linking to some demos, but can't find it

Dan: we could ask him

Peter: I know he has these resources. He can probably link us.

Lea: Might be easier to wrap our heads around it if we have a presentation

Hadley: separate call?

Dan: let's ask some questions, then decide if we want to bring someone in

Lea: there are code samples without visuals.. I'm having trouble connecting code samples with the output

Dan: yes

Lea: some are more clear. The customisation of animations section is the most clear one. That is what got me to understand. But animating width and height shows a nice animation. What is the code that produces that animation? How do you get that kind of effect? I don't understand.

Rossen: transition both the width and height properties into 100%

Lea: that is not the only thing that is happening there

Dan: under that one there's a link that says this is relatively easy...

Lea: [clicks link]. Before formulating questions I need to spend more time in case there are links with answers.. I want to respect the time they spent writing that.

Dan: there's a lot of links to a chrome developer document from about a year ago which ... should be in the explainer

Lea: I can ask about examples more tied to animations

Peter: let's just ask Jake if he has more concise code, then look at that then decide. Agree with Lea, obviously a lot of effort went in. But as I go through this there's a lot of handwaving and presumptions of knowledge which is not necessarily clearly laid out in the explainer. Big chunks I'm missing. Not seeing.. to me a lot of the design of this feels weird. I accept that it's probably necessary, but why the design turned out this way and the reasons is not explained either

Lea: yeah, there must be something we're missing..

Peter: some shared knowledge that is not being expressed

Dan: maybe we need to ask them to write down more explicitly use cases.. they are expressing use cases, but I'm not sure.. sentence about ...

Rossen: what if you ask Jake to provide .. to pick any two examples and provide the end to end code.

Discussed Aug 1, 2022 (See Github)

Dan: noting jake responded to Lea's comment. Great!

Peter: I have some other concerns on the CSS side of this - will dig into it and formulate my thoughts... structure of pseudo-elements feels weird to me... Let's bump to next week.

Discussed Aug 1, 2022 (See Github)

punt to plenary

Comment by @jakearchibald Aug 12, 2022 (See Github)

Hey folks, we just updated the explainer. It should give a better overview of the feature now https://github.com/WICG/shared-element-transitions/blob/main/explainer.md.

The previous version was written before we had a spec, so included some lower-level detail which is better left to the spec.

Comment by @LeaVerou Aug 17, 2022 (See Github)

Hi Jake,

We looked at this during the plenary today. We generally recognize the importance of solving these very common use cases and understand that to cover enough of them, the solution would need a certain degree of complexity. However, we did have some trouble wrapping our heads around exactly how this works and how the different pieces fit together. While it is very clear that a lot of effort has been put into this explainer, we also feel that some parts assume certain knowledge about the reader. We would like to see more examples of both code and output, as well as some simpler examples that may not look nice, but illustrate how the API works. A few hello worlds of sorts 😊 Or perhaps it may help to pick two of these examples and provide the end to end code for them somewhere?

Comment by @jakearchibald Aug 18, 2022 (See Github)

Does the developer guide provide that kind of introduction? https://developer.chrome.com/blog/shared-element-transitions-for-spas/ - each of the demos has a video, but also a link to a super simple example. There's also a 10 min video on the feature if that works better https://www.youtube.com/watch?v=JCJUPJ_zDQ4.

The difference between the developer document and the explainer, is the explainer uses the latest API (which hasn't landed in Chrome yet), and contains a few more implementation details.

Comment by @LeaVerou Aug 18, 2022 (See Github)

Yes! At least for me this was a lot clearer. Is there anything similar about MPAs?

Comment by @jakearchibald Aug 18, 2022 (See Github)

There's https://github.com/WICG/shared-element-transitions/blob/main/explainer.md#cross-document-same-origin-transitions in the explainer.

Comment by @jakearchibald Aug 19, 2022 (See Github)

What are the next steps here? I could merge the more-gradual-introduction from https://developer.chrome.com/blog/shared-element-transitions-for-spas/ into the explainer.

Comment by @LeaVerou Aug 19, 2022 (See Github)

The next step is that we revisit this in another call. I see it now has a milestone of 2022-08-22-week, which means the intent is to revisit it next week.

I wonder if part of the reason it was so hard to wrap our heads around this was that the explainer was already very long, so it was hard to know what to focus on when reviewing it during the call. This is a complex feature, so it does need a lot of, well, explaining, but I wonder if it might be easier to digest if organized hierarchically, breadth-first. Also, despite the length, we felt there were certain pieces of the puzzle missing, e.g.:

  • Some TAG members felt the problem statement was explained insufficiently. How is this different than existing transition & animation features and what are the use cases?
  • I personally got very confused at the JS code snippet:
const transition = new SameDocumentTransition();
await transition.prepare(async () => {
  await updateTheDOMSomehow();
});

that is just repeated throughout the explainer. It took until the link you posted above for me to finally understand how this works: You start the transition by creating a new SameDocumentTransition instance, then make the changes to create this transition in the transition.prepare() callback.

  • The pseudo-element tree is described, but it's never explained what each of these pseudo-elements is, what does it represent, and why do we need so many of them. Several of us found this confusing. Things like the exact UA styles for these could have been in some sort of appendix instead of being the main content about these pseudos. All the explainer needed to say about this was that there are UA styles in place that make sure the default transition is a cross-fade, and that the animation is customized by overriding these UA styles.
  • In general, it feels like the explainer skips over explaining things that would actually provide context to someone coming to this feature with a blank slate, and yet talks at length about things that are exceptions or edge cases. These are of course useful to know as well, but only after the basics have been understood, which was not the case for all of us.

Hope this helps a bit!

While writing this, I had some thoughts about the actual API: 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?). As an author, I wouldn't even know how to use transition.prepare() when using a framework that does the DOM manipulation for me.

I also just noticed that this doesn't support MPAs yet, but that's an API sketch. Since that's a pretty central use case, I'll make sure we spend call time reviewing that sketch too, and not just the SPA part of the API.

Comment by @jakearchibald Aug 19, 2022 (See Github)

This is great feedback. What day & time are folks likely to look at this? As in, assuming I'm not working the weekend (which I plan not to), how long do I have to bash the explainer into shape?

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:

const transition = new SameDocumentTransition();
await transition.prepare(async () => {
  await updateTheDOMSomehow();
});

…could have an alternative API like:

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 use a similar pattern for this reason.

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 https://http203-playlist.netlify.app/ uses. React has useLayoutEffect for hearing about DOM changes before the next render.

Comment by @plinss Aug 19, 2022 (See Github)

Our current schedule is to look at this again on 8/22 @18:00CET, but we can easily defer a week or two if you need more time.

Comment by @jakearchibald Aug 19, 2022 (See Github)

I'm up for the challenge. I'll confirm here when I've updated the explainer.

Comment by @jakearchibald Aug 22, 2022 (See Github)

Done! https://github.com/WICG/shared-element-transitions/blob/main/explainer.md

Hopefully the explainer now starts off at a high level, then goes on to explore some of the details. For additional details, the spec may be useful https://tabatkins.github.io/specs/css-shared-element-transitions/.

If it still isn't good, and you need to bail on it, there's always https://github.com/w3ctag/design-reviews/issues/761 to review instead 😄

Comment by @LeaVerou Aug 24, 2022 (See Github)

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:

const transition = new SameDocumentTransition();
await transition.prepare(async () => {
  await updateTheDOMSomehow();
});

…could have an alternative API like:

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 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:

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

whereas with your alternative API sketch:

const transition = animationsEnabled && globalThis.SameDocumentTransition ? 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.

Note that the current API can still cause rendering to freeze, if you await a promise that never resolves.

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 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.

Comment by @jakearchibald Aug 24, 2022 (See Github)

I understand, but the callback model makes this very annoying to use w/ progressive enhancement Branching is still possible with this API, but very cumbersome and boilerplatey:

In the simple case, we're talking:

function spaNavigate(data) {
  // Fallback for browsers that don't support this API:
  if (!self.SameDocumentTransition || !animationsEnabled) {
    updateTheDOMSomehow(data);
    return;
  }

  const transition = new SameDocumentTransition();
  transition.prepare(() => updateTheDOMSomehow(data));
}

Vs:

async function spaNavigate(data) {
  const transition =
    animationsEnabled && self.SameDocumentTransition
      ? new SameDocumentTransition()
      : null;
  await transition?.captureBeforeState();
  await updateTheDOMSomehow();
  transition?.domChanged();
}

(both examples formatted with https://prettier.io/)

I'm not sure the latter is less cumbersome. Every time you interact with transition?, you need to think about the 'null' case too.

Once you start adding more transition-specific script:

thumbnail.onclick = () => {
  if (!self.SameDocumentTransition || !animationsEnabled) {
    updateTheDOMSomehow(data);
    return;
  }
  const transition = new SameDocumentTransition();
  thumbnail.style.pageTransitionTag = "full-embed";
  transition.prepare(() => {
    thumbnail.style.pageTransitionTag = "";
    updateTheDOMSomehow();
  });
};

Vs:

thumbnail.onclick = async () => {
  const transition =
    animationsEnabled && self.SameDocumentTransition
      ? new SameDocumentTransition()
      : null;
  thumbnail.style.pageTransitionTag = 'full-embed';
  await transition?.captureBeforeState();
  thumbnail.style.pageTransitionTag = '';
  updateTheDOMSomehow();
  transition?.domChanged();
};

Again, this doesn't seem particularly better, and now you're running steps that are for transitions, even in cases where you're not actually wanting a transition. In this case it's a no-op, but as the author and the reader, you need to think that through. Or, alternatively, avoid those steps if it isn't a transition:

thumbnail.onclick = async () => {
  const transition =
    animationsEnabled && self.SameDocumentTransition
      ? new SameDocumentTransition()
      : null;
  if (transition) {
    thumbnail.style.pageTransitionTag = 'full-embed';
  }
  await transition?.captureBeforeState();
  if (transition) {
    thumbnail.style.pageTransitionTag = '';
  }
  updateTheDOMSomehow();
  transition?.domChanged();
};

And now this is looking much more complicated than the first example. Things get worse still when you're wanting to also control parts of the transition with script. And still, there's the timeout issue if the DOM change throws.

and the Web Platform in general is trying to move away from callback-based APIs.

This is news to me, and I'm not sure it's true. Cases where an API wants to know the async result of a developer action are commonly callbacks.

Some modern examples:

These kinds of cases don't really make sense as promises, because it isn't purely waiting for a response from the API, it's also providing a response to the API. These kinds of cases don't really make sense as events either, since they only really have one listener, and the response may be async.

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)

That kind of lag is acceptable when it comes to reaction to a click, but pausing animations for 60ms is very noticable. So if the DOM change actually failed in 5ms, I'd rather not have a 60ms lag.

You could also take a signal to abort the operation, which is good practice anyway.

We currently have an .abandon() method on transitions, but I want to rename this .skipTransition(), or something that communicates that only the transition will be skipped, it won't skip the DOM change (unless you skip that in some other way).

One of the mistakes we made in some of the earlier designs of this API is trying to be a scheduler for the DOM change, but I think we really need to focus on transitions only. The Navigation API provides an abort signal for abandoning DOM changes, and frameworks that perform DOM changes asynchronously already have their own scheduling systems.

Note that the current API can still cause rendering to freeze, if you await a promise that never resolves.

Yeah, although it's generally only faulty promises that do that. Those cases are caught by the timeout. But I'd rather not rely on the timeout for cases where the error can be easily caught.

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.

I've never written anything in Vue before, but I can try and cook up a demo. Do you have an example of how you'd use something like ResizeObserver with Vue? That would give me a good start I think.

Comment by @jakearchibald Aug 25, 2022 (See Github)

Here's a demo created in Vue https://8trrx7.csb.app/ (runs in Chrome Canary with the document transition flag).

Here's the code https://codesandbox.io/s/busy-kepler-8trrx7?file=/src/App.vue.

Assuming this is how you'd increment a number in Vue:

export default {
  data: () => ({
    num: 1,
  }),
  methods: {
    incrementNum() {
      this.num += 1;
    }
  }
};

Here's how you'd increment it with a transition:

import { nextTick } from "vue";

export default {
  data: () => ({
    num: 1,
  }),
  methods: {
    incrementNum() {
      const update = () => (this.num += 1);

      if (!self.SameDocumentTransition) {
        update();
        return;
      }

      new SameDocumentTransition().prepare(async () => {
        update();
        await nextTick();
      });
    },
  },
};

This seems… fine? It's roughly the same as the plain DOM example, except for the addition of nextTick. I've never written anything in Vue before, so maybe I'm breaking some best practices?

A Vue helper could be created for this:

import { nextTick } from "vue";

export function transitionStateChange(stateChangeCallback) {
  if (!self.SameDocumentTransition) {
    stateChangeCallback();
    return;
  }

  new SameDocumentTransition().prepare(async () => {
    stateChangeCallback();
    await nextTick();
  });
}

Which could be used like this:

export default {
  data: () => ({
    num: 1,
  }),
  methods: {
    incrementNum() {
      transitionStateChange(() => (this.num += 1));
    },
  },
};
Comment by @jakearchibald Aug 26, 2022 (See Github)

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

Fwiw, we've decided to automatically skip transitions in the prefers-reduced-motion case, unless the developer opts in. https://github.com/WICG/shared-element-transitions/issues/19#issuecomment-1227075082

Update: This decision was reversed in favour of a solution that covers other types of motion too.

Comment by @khushalsagar Aug 30, 2022 (See Github)

The spec is now at csswg drafts here: https://drafts.csswg.org/css-shared-element-transitions-1/

Comment by @khushalsagar Sep 8, 2022 (See Github)

Heads up, we'll have a session on this feature at TPAC on Wednesday. I'll post the exact time next week. Looking forward to see folks interested there!

Comment by @khushalsagar Sep 13, 2022 (See Github)

The breakout session is on September 14 at 3 PST. Details are here including a link to join virtually.

Discussed Oct 1, 2022 (See Github)

Lea left comment asking if the TPAC session was recorded.

Comment by @vmpstr Oct 5, 2022 (See Github)

Hey TAG, I was wondering if you had a chance to take another look at this proposal?

Comment by @LeaVerou Oct 24, 2022 (See Github)

The breakout session is on September 14 at 3 PST. Details are here including a link to join virtually.

Hello, has this session been recorded? It would help us with this review.

Comment by @khushalsagar Oct 24, 2022 (See Github)

Unfortunately we don't have a recording for that session but the scribed minutes are here: https://www.w3.org/2022/09/14-pagetransitions-minutes.html.

And the slides used in the session are here: https://lists.w3.org/Archives/Public/www-archive/2022Sep/att-0007/set-slides.pdf

Discussed Nov 1, 2022 (See Github)

Peter: some activity in CSS about this having to do with pseudo-elements. Has the explainer been updated to reflect those changes?

Dan: there has been some pushback on our points but do we care enough?

Lea: this seems too complex.

Peter: i feel the same way - too complicated and bolted onto the side... Also this is a complicated problem to solve so this may be the best solution.

Lea: kind of inclined to say "OK" ...

Peter: i feel like i need to play with it to better understand it.

Lea: they want to push it forward...

Lea: the concerns are about complexity...

Peter: if we just say "yes we have concerns we think this is too complex" i don't think that will cause them to step back and revisit their design. My concern is : is this the right approach? I hate to give them that feedback without understanding a better way to do this.

Dan: can we couch it in terms of developer ergonomics. something about layering?

Peter: if we can't easily wrap our head around it... Authors should get some high level thing that they can just use... I'd like to see that.

Dan: can we leave feedback ....

Lea: there's an experimental implementation in chrome...

Dan: have developers been using it?

Lea: that would be great...

Dan: something like:

<blockquote> Current status: we're concerned about developer complexity and ergonomics. Can the requestors address this issue: how will developers actually us this?

Do you have any feedback from the current exerpiemntal implementation that could help to answer this question?

Is the implementation up to date with the current syntax?

</blockquote> <blockquote>

@jakearchibald

We looked at this again today and had some questions:

  • Is the current experimental implementation in Chrome up to date with the current syntax?
  • Do you have feedback from authors that have used the experimental implementation? Have you observed any of them using it and seen what they struggle with?

We are particularly concerned about the complexity and ergonomics of this API, and we (TAG members) have not yet had the a-ha moment where we fully understand how all the pieces come together to create a transition in a real use case from scratch. Given the trouble we've had with it, that gives us some pause about DX in the wild. Perhaps it's an inherently complicated problem and there cannot possibly be a simpler solution, but it is a concern that came up several times in our discussions.

Regarding https://github.com/w3ctag/design-reviews/issues/748#issuecomment-1225922770 , the main issue I see is that with the current API, updateTheDomSomehow() needs to be repeated twice, which is fine when it's a separate function, but it means all such DOM modifications need to become separate functions, which as an author I'd find annoying.

</blockquote>

lea to leave comment

Discussed Nov 1, 2022 (See Github)

bumped to plenary

Comment by @LeaVerou Nov 16, 2022 (See Github)

We looked at this again today and had some questions:

  • Is the current experimental implementation in Chrome up to date with the current syntax?
  • Do you have feedback from authors that have used the experimental implementation? Have you observed any of them using it and seen what they struggle with?

We are particularly concerned about the complexity and ergonomics of this API, and we (TAG members) have not yet had the a-ha moment where we fully understand how all the pieces come together to create a transition in a real use case from scratch. Given the trouble we've had with it, that gives us some pause about DX in the wild. Perhaps it's an inherently complicated problem and there cannot possibly be a simpler solution, but it is a concern that came up several times in our discussions.

@jakearchibald

Regarding https://github.com/w3ctag/design-reviews/issues/748#issuecomment-1225922770 , with the current API, updateTheDomSomehow() needs to be repeated twice, which is fine when it's a separate function, but it means all such DOM modifications need to become separate functions, which as an author I'd find annoying.

Re:frameworks, I’m sure it's possible, and yes it doesn't look too bad, but it's unfortunate that it requires people to find out implementation details like nextTick() that don't come up during typical framework usage, and are different per framework. I think the current callback API is less friendly to the multiple layers of abstraction in modern web apps. It's not the end of the world if it doesn't change, but I still think not having a callback would serve the majority of cases better.

Comment by @khushalsagar Nov 16, 2022 (See Github)

Is the current experimental implementation in Chrome up to date with the current syntax?

Yes. Canary is up to date, the last syntax changes landed in 109.0.5410.0.

Do you have feedback from authors that have used the experimental implementation? Have you observed any of them using it and seen what they struggle with?

Feedback from authors has been quite positive since the pseudo-DOM structure can be animated using existing APIs and debugged via existing devtools support. A few interesting patterns which have come up from experimentation are:

  • Avoiding a long delay when rendering is paused, waiting for the new DOM to load. They'd like some animation to give the user feedback that content is loading.

    • This delay is in author's control since it depends on how long the updateDOM callback takes. So we've seen authors do most of the latency sensitive work (network fetches) before triggering the transition. This allows the page to remain interactive. Authors can also add a spinner (or another animation) before the transition to give loading feedback.
    • Another (more common) strategy is taking the user to a skeleton page which suffices for the basic transition and then lazily loading large assets like images.
  • Keeping an element continuously animating throughout the transition, in particular a video. Again if the author callback is fast then the duration the video doesn't update is limited to how long the browser takes to snapshot which is 2-3 frames long and not noticeable. @jakearchibald made a demo which shows this (works in current chrome canary with chrome://flags/#view-transition enabled).

We had a breakout session describing how the feature works at BlinkOn today. I'll post a link of the recording which would hopefully help with understanding the full design.

Will let @jakearchibald comment on the ergonomics of the callback based API.

Comment by @jakearchibald Nov 17, 2022 (See Github)

@LeaVerou

Regarding #748 (comment) , with the current API, updateTheDomSomehow() needs to be repeated twice, which is fine when it's a separate function, but it means all such DOM modifications need to become separate functions, which as an author I'd find annoying.

I don't think this will be a huge issue in practice, as I expect developers will write a little helper function like this:

async function doViewTransition(callback) {
  const skipTransition =
    !document.startViewTransition ||
    matchMedia('(prefers-reduced-motion)').matches ||
    localAppConfig.skipTransitions;

  if (skipTransition) {
    callback();
    return null;
  }

  await document.startViewTransition(callback).domUpdated;
}

Then the usage would be:

await doViewTransition(() => {
  header.classList.add('whatever');
});

Even in a world where all browsers support view transitions, a helper is handy for centralising skipping transitions for reasons that are specific to the site (like reduced motion and localAppConfig.skipTransitions in the above example).

Re:frameworks, I’m sure it's possible, and yes it doesn't look too bad, but it's unfortunate that it requires people to find out implementation details like nextTick() that don't come up during typical framework usage, and are different per framework. I think the current callback API is less friendly to the multiple layers of abstraction in modern web apps. It's not the end of the world if it doesn't change, but I still think not having a callback would serve the majority of cases better.

I don't think there's a model we can adopt where you wouldn't need to know about nextTick() in Vue. In order to create a transition, we need to capture the before state, and the after state. The problem is, Vue abstracts and defers the DOM changes, so you're reliant on the framework providing some sort of signal that it applied the changes you requested, and in Vue that's nextTick(). If that's tricky… that's on Vue for not providing an easy way to know when the changes you asked for actually happened.

My hope is that each framework will have a hook/component that wraps this, and turns state changes into transitions, similar to what they already do with animations, but with much less code.

If you haven't had an a-ha moment with this, then my docs suck. That's probably because I'm too deep in the spec/implementation. Would you be up for a video call where we talk through the API & examples? Hopefully the a-ha moment will happen, and you can tell me what details should have been at the very top of the docs, in bold, rather than buried somewhere 😄

Comment by @khushalsagar Nov 19, 2022 (See Github)

And here is a recording of the session at BlinkOn. It's focused on Blink/Chromium specific implementation details for some parts but covers the general web platform concepts too.

Discussed Dec 1, 2022 (See Github)

Lea: we talked aout developer complexity -- jake wants to have a call - we haven't scheduled it yet.

dan reschedules for week of jan-9 and Lea will try to set up call with Jake before then

Discussed Jan 1, 2023 (See Github)

Lea: I had a call with Jake Archibald - we went through some demos - it's more clear to me how this API works... My concerns were - there's a lot that has to be done with JS. There's a declarative version - same API for multip page and single page apps. For SPA it requires JS. For MP there's a declarative version. A way to solve the declarative problem... use JS for the transition as well..(?) Transition itself is specified in CSS. View transition name needs to be unique... Failure mode inconsistent with web platform... No way to specify if you want a different transition depending on pages or elements... unless you hack together with more JS. Biggest take-away: I do think it's usable as is. I would like simple cases to be possible to do declaratively. You still do some wrangling with JS. Say you're animating from a list of things with images to a full page showing the image. The way you use the API - you add a class to the thing you clicked and then remove that class and add it elsewhere... Still more simple than with CSS, where you have to wrangle a lot more things...

... You can enable flags in Chrome Canary... if you want to play with it...

deep thought ensues

Peter: where do we go?

Lea: Satisfied with concerns? There is a strong user need. As long as you're willing to write JS it's OK. my main concern is you have to write JS in some cases where you don't have to otherwise. Other concern: you must [...] the DOM manipulation (in SP version) ... if you want to add a transition you depend on the library firing the right event...

Peter: how would you do it declaratively? If you're going to wind up making changes to the DOM.

Lea: when you click an element and it gives you more detail - how do you declare which element is the staring one since CSS doesn't give you a mechanism for that? It would be nice if there was a way to say. Since the browser knows when the DOM has been manipulated.

Peter: my concern: is there anything about the design that preculdes declarative - probably not. The point about not being able to have different transitions depending on what the elements are is concerning.

Lea: also what the pages are in multi-page. Transitions are supposed to communicate meaning, not be only decorative. If it doesn't matter where you're coming from and going, they are just decorative.

Peter: should be addressed in future.

Lea: it could be worked around...

Peter: give feedback to ask if they've thought about that... Let's not paint ourselves into a box... with an API design that makes it difficult to add later.

Lea: I can give that feedback.

Rossen: I have thoughts.

Lea: my questions were answered today... They are already thinking about transitions dependant on elements

Rossen: so not precluded by the current design?

Lea: Correct. Concern about.. if you use a view transition name that is a duplicate you get a warning, is that consistent with the rest of the web platform?

Peter: if it just goes and spits out a warning that seems odd

Lea: you lose the transition altogether, and it spits out a warning

Rossen: you can't even handle it easily?

Lea: you can't because its CSS.

Peter: is the case where you have multiple things with the same name.. in CSS specificity wins

Lea: right, in most things in CSS. With this new css property that's not how it works. If you have a duplicate view transition name.. if you specify the same view transition name on two elements - and the way css selectors work makes this very easy - you're supposed to manually make sure you only apply this to one element in the entire tree. If you have duplicate ones, no transition happens, you just get a warning. The reasoning being maybe in the future they might want to do something clever with multiple elements that have the same view transition name. So that might make it easier. Seems to me CSS printing out a warning is nto very consistent. We even have a principle about declarative syntax shouldn't throw warnings somewhere, at least to html. Maybe should expand to CSS.

Peter: the issue is when you have the same transition declared for multiple elements? Not multiple transitions with the same name?

Lea: you use the same transition name on the start and end state,s which could be different or same elements. Same property with an identifier. If you use that on multiple elements at the same time that is a problem. When you use it to specify the start and end state you're supposed to add the name on the starting element and at some point you move it to the end state element. Unclear to me at what point that happens.

Peter: warning if multiple elements have the view transition name at the same time?

Lea: yes. Then you don't get a transition at all.

Peter: does seem weird

Lea: I wonder if a better design might be to explicitly say what is the start and end state, instead of a property that does both at once. But haven't thought about it as much as they have, maybe there's a reason not to do it that way.

Peter: could ask

Rossen: and ask if using root as the name would ever work? If you look at the clarification they have about using the view transition name custom ident it's defined as the element can participate.. as either a node or new element with view transition name equal to custom ident value.. [reads] ... so now if I go and add a transition called root, what happens? Do I get a warning and the document elements one doesn't work?

Lea: [will ask]

<blockquote>

@jakearchibald and I had a call about this yesterday, and I think I now understand how this works and how the different pieces come together a lot better. We later discussed this again with other TAG members in a breakout.

We are aware that you have all been thinking about this for a lot longer than we have, and it's entirely possible that you've already explored all this and concluded the current API shape is a necessary compromise, but in case it helps, these were our thoughts:

  • We like that MPA transitions are declarative, and would love to see a declarative syntax for SPA transitions too, as right now the two APIs feel a bit disconnected. It's also an antipattern if an author needs to write JS to animate a DOM manipulation or navigation that was not fired through JS. A declarative way to transition hash navigations within the same document could address some of that. Perhaps also a declarative way to filter view transitions by container and types of DOM mutations? This would also facilitate enhancing behavior from third party scripts with view transitions, as these often use their own events, which makes it hard to time the JS call.
  • It looks like CSS would be a more appropriate place for the declarative opt-in, rather than an HTML <meta> element which cannot be customized by media queries or scoped to elements in the future.
  • We think it's essential to be able to customize the transition easily based on the elements or pages that are participating in it. Good transitions communicate, they are not just decorative. If the API makes it simple to have the same transition regardless of what is transitioning to what, but tricky to customize it, it facilitates transitions which are merely decorative.
  • We think that skipping the transition and showing a warning when there is a duplicate view-transition-name is not Web Platform compatible. Typically in the declarative languages of the Web Platform, when something needs to be unique but isn't, is still handled gracefully (e.g. by using the first or the last one). Especially this being a CSS property, it's very easy to accidentally specify it on multiple elements, simply because it's very easy to specify selectors that match multiple elements. Also, since the root has view-transition-name: root anyway, how do you use that without having duplicate transition names?

We wondered if it could prevent some of these issues and allow more room for future expansion if view-transition-name distinguished between the start and end state (e.g. through old and new keywords, possibly used together if the same element is both). That also prevents the user having to time when view-transition-name: foo will be removed from the start state and added to the end state: both can happen at once, at the same time as the event that kicks off the transition.

In general, we'd like to see a layered, gradual approach, where a small amount of declarative CSS syntax can address common use cases, more CSS can customize the transitions further, and JS is needed to customize behavior even further than that. This is also in line with how existing CSS transitions and animations work, where syntax is gradually added to customize further, but very little syntax is needed to produce an initial result.

We also think tighter collaboration between the designers of this API and the CSS WG could help address some of these issues.

</blockquote>
Comment by @LeaVerou Jan 10, 2023 (See Github)

@jakearchibald and I had a call about this yesterday, and I think I now understand how this works and how the different pieces come together a lot better. We later discussed this again with other TAG members in a breakout.

We are aware that you have all been thinking about this for a lot longer than we have, and it's entirely possible that you've already explored all this and concluded the current API shape is a necessary compromise, but in case it helps, these were our thoughts:

  • We like that MPA transitions are declarative, and would love to see a declarative syntax for SPA transitions too, as right now the two APIs feel a bit disconnected. It's also an antipattern if an author needs to write JS to animate a DOM manipulation or navigation that was not fired through JS. A declarative way to transition hash navigations within the same document could address some of that. Perhaps also a declarative way to filter view transitions by container and types of DOM mutations? This would also facilitate enhancing behavior from third party scripts with view transitions, as these often use their own events, which makes it hard to time the JS call.
  • It looks like CSS would be a more appropriate place for the declarative opt-in, rather than an HTML <meta> element which cannot be customized by media queries or scoped to elements in the future.
  • We think it's essential to be able to customize the transition easily based on the elements or pages that are participating in it. Good transitions communicate, they are not just decorative. If the API makes it simple to have the same transition regardless of what is transitioning to what, but tricky to customize it, it facilitates transitions which are merely decorative.
  • We think that skipping the transition and showing a warning when there is a duplicate view-transition-name is not Web Platform compatible. Typically in the declarative languages of the Web Platform, when something needs to be unique but isn't, is still handled gracefully (e.g. by using the first or the last one). Especially this being a CSS property, it's very easy to accidentally specify it on multiple elements, simply because it's very easy to specify selectors that match multiple elements. Also, since the root has view-transition-name: root anyway, how do you use that without having duplicate transition names?

We wondered if it could prevent some of these issues and allow more room for future expansion if view-transition-name distinguished between the start and end state (e.g. through old and new keywords, possibly used together if the same element is both). That also prevents the user having to time when view-transition-name: foo will be removed from the start state and added to the end state: both can happen at once, at the same time as the event that kicks off the transition.

In general, we'd like to see a layered, gradual approach, where a small amount of declarative CSS syntax can address common use cases, more CSS can customize the transitions further, and JS is needed to customize behavior even further than that. This is also in line with how existing CSS transitions and animations work, where syntax is gradually added to customize further, but very little syntax is needed to produce an initial result.

We also think tighter collaboration between the designers of this API and the CSS WG could help address some of these issues.

Comment by @khushalsagar Jan 11, 2023 (See Github)

We like that MPA transitions are declarative, and would love to see a declarative syntax for SPA transitions too, as right now the two APIs feel a bit disconnected. It's also an antipattern if an author needs to write JS to animate a DOM manipulation or navigation that was not fired through JS.

Completely agreed with the goal to keep the syntax as declarative as possible. I’ll clarify the challenge with being able to do the work of the JS API with a declarative syntax, and would love to hear TAG’s ideas for it.

The JS API is needed because the UA needs an explicit signal to render and cache the old DOM state before the DOM is changed. This signal doesn't need to be JS-driven, as proven by the MPA version of the API which uses cross-document navigations as the signal. The only difference between the MPA and SPA versions of the API is this signal, the rest is the same. In SPAs, JS is already driving the DOM change, so it seems reasonable for JS to be used to signal these states. It wouldn't be impossible to do this all in CSS (in theory we can add as much syntax as we want), but I'm not confident it would be easier for developers to use.

A good example for a DOM change triggered declaratively would be the :hover pseudo-class. A strawman proposal for a completely declarative view transition in this case would require:

  1. A declarative signal that a change in this pseudo-class state for this DOM element should initiate a view transition. If multiple elements have a state change (becoming inactive on 1 element and active on another element), we have to select one transition.
  2. A declarative way to identify this transition so the author can mark up view-transition-names specific to this transition.
  3. The UA needs to snapshot the old DOM before toggling the pseudo-class state during style computation.
  4. Once the above is done, toggle the pseudo-class state and continue the transition as usual.

Admittedly I don't know how this could be done in JS, and it attests to your point that there are cases where declarative syntax would be needed. However, that doesn't mean we couldn't add additional ways to provide this signal going forward for such cases. The design of view-transitions allows for this kind of thing to be explored.

A declarative way to transition hash navigations within the same document could address some of that.

+1 for declarative transitions on hash navigations, this has come up before. Filed #8300 to discuss this in CSSWG.

Perhaps also a declarative way to filter view transitions by container and types of DOM mutations?

I’m assuming you mean transitions for changes in a third party component which doesn’t provide the requisite signals required by document.startViewTransition(). I don’t see how a CSS solution would solve this over JS. It does sound similar to scoped transitions which would allow multiple concurrent transitions on a page, scoped to a DOM sub-tree. This way a third-party widget can have its internal transitions without leaking any details to the embedding page.

It looks like CSS would be a more appropriate place for the declarative opt-in

Agreed. #8048 is tracking that.

We think it's essential to be able to customize the transition easily based on the elements or pages that are participating in it.

There are going to be declarative hooks for the common customization cases in CSS. For instance, based on the old/new Document URL; or by pages assigning themselves a tag/name/class/category which can be used in CSS. It might be more ergonomic to express the customization based on going from “index” to “article" rather than going from / to /2023/01/happy-new-year/?utm-matrix=abcdef.

The JS component of the cross-document API could also allow passing opaque contextual data between pages for this customization but this warrants more discussion, filed #8303 for this.

Note that the API surface specific to cross-document/navigation triggered transitions is in very early stages right now. There is a prototype but the MPA API is being iterated on as level 2 of this spec, you can see CSSWG issues here.

We'd like TAG to scope this review to the CSS component of this API, which is common to SPA/MPA, and the SPA specific JS API.

Especially this being a CSS property, it's very easy to accidentally specify it on multiple elements, simply because it's very easy to specify selectors that match multiple elements.

The rationale for skipping the transition was to make it easier for developers to spot an error with a hard failure rather than a graceful fallback which masks it. If the view-transition-name is not unique and wrong elements are matched together, the transition could look very incorrect visually. Skipping it allows developers to fallback to old behaviour and also monitor how often it's happening, in case they are hitting a bug in production.

There are use-cases which need a common identifier for a set of tagged elements, discussion at #8209. This can be added in the future, we haven't designed ourselves in a corner here.

Also worth noting is the design principle that Transitions are an enhancement, so we don't see skipping the transition as a failure. We might, on really low-end devices, or devices in some constrained mode, choose to always skip transitions.

since the root has view-transition-name: root anyway, how do you use that without having duplicate transition names?

Developers can override this with a style rule, similar to overriding any other rule in UA CSS.

We wondered if it could prevent some of these issues and allow more room for future expansion if view-transition-name distinguished between the start and end state

It isn't clear what problem this solves, duplicate view-transition-names would be a developer bug. I understand that ensuring this in CSS can be difficult but it's a fundamental requirement to ensure correct matching of DOM elements for animations.

That said, your suggestion for distinguishing view-transition-name between start/end states can be added in the future if a use-case emerged. For example, view-transition-name-old only applied when discovering elements in the old DOM and view-transition-name-new only for elements in the new DOM. The existing view-transition-name then becomes a shorthand which sets both, preserving current behaviour.

That also prevents the user having to time when view-transition-name: foo will be removed from the start state and added to the end state: both can happen at once, at the same time as the event that kicks off the transition.

A pattern I’ve seen to do this is toggling the class name on the root element:

document.documentElement.classList.add(“transition-old”);
document.startViewTransition(() => {
   document.documentElement.classList.remove(“transition-old”);
   document.documentElement.classList.add(“transition-new”);
});
}
html.transition-old .element-foo {
   view-transition-name: target;
}

html.transition-new .element-bar {
   view-transition-name: target;
}

There are probably better ways to do this. Given that the author already has to time their DOM update in the callback passed to startViewTransition, it doesn’t seem like an issue to have to update view-transition-name as a part of the DOM update?

In general, we'd like to see a layered, gradual approach, where a small amount of declarative CSS syntax can address common use cases, more CSS can customize the transitions further, and JS is needed to customize behavior even further than that. This is also in line with how existing CSS transitions and animations work, where syntax is gradually added to customize further, but very little syntax is needed to produce an initial result.

IMHO the API already requires minimal CSS for the common use cases. For a root transition which is a simple cross-fade, no CSS is necessary. For transitions morphing one widget into another, the developer needs to only add view-transition-name to the corresponding DOM elements. Transitions can be customized further with more CSS or JS, and built on top of existing animation primitives on the web (CSS animations or web animations). But none of that is needed if the default UA animations suffice.

What we haven’t been able to do is a no JS syntax for basic SPA transitions. You need at least 1 line of JS to make that work:

document.startViewTransition(updateToNewState);

And that’s because any basic SPA app will drive DOM changes via JS internally. They will already have script which invokes updateToNewState along with mutations to the navigation history. So it doesn’t seem too difficult to wrap that call in the syntax above. We could consider invocations to history.pushState as an implicit signal for triggering a transition. But now we’re adding unnecessary tight coupling with the navigation APIs. And there will still be cases where DOM changes don’t necessarily mutate the navigation history.

So the minimal JS API is unavoidable for the same-document (SPA) API. The MPA API can be script free because these JS events are implicit in the navigation. A JS free API for same-Document transitions is definitely useful for a subset of cases but doesn’t need to be a goal for v1 of this feature.

We also think tighter collaboration between the designers of this API and the CSS WG could help address some of these issues.

I believe this is already the case. We had multiple breakout sessions with CSSWG during the early incubation period. Those sessions are recorded in #6464, which also includes WG’s resolution for the spec to go to FPWD. All non-trivial changes have gone through CSSWG resolutions as well. I’m happy to take suggestions for more engagement with CSSWG.

Discussed Feb 1, 2023 (See Github)

Lea: long thread... I had a breakout with Jake Archibald. Still had some concerns that I outlined in a comment. Had a response but not fully digested.

Lea: at this point we're going into the weeds. We've gone back and forth extensively.

Dan: have they been responsive to our feedback?

Lea: Yes.

Dan: Maybe it is a good point to close and ask them to keep us updated. We've already raised complexity concern. "We are particularly concerned about the complexity and ergonomics of this API." Can we give them a challenge to work to explain this API to developers, especially considering the complexity factor?

Lea: I don't think the problem is documentaiton. I think the explainer makes a lot of sense. I think the explainer does a good job of explaining how the API works. The latest feedback on jan 10 was about other issues.

Lea: i'm thinking we should say "we have some concerns - we like overall that you've been working on this - thank you for being receptive to our feecback - please keep us updated."

Dan: agree. What's the issue outcome? "with concerns"?

Lea: the fact that you have to write js for things that don't otherwise require js is an antipattern. That you can't write transitions fo rthings triggered by 3p libarries you're not controlling. Fairly complex to hook into that. Wrap the entire transition into a callback. also understand the rationale, but it's a concern. Would like them to look at our feedback and try to address it - I think they are doing that, trying to think about it and filing issues.

Peter: agree "satisfied with concerns". Looks like there is work to do and it is being done

Comment by @LeaVerou Feb 20, 2023 (See Github)

Thank you for being responsive to our feedback. We circled back at this today in a breakout and we have consensus that our work here is done for now. We do have concerns about this API, discussed above, but are also optimistic that these are being worked out, and we do think this is functionality that is very useful for developers. We are looking forward to seeing how this API evolves to be more usable in a wider variety of use cases. We will close this for now, feel free to re-request a review if you make substantial changes.