Re: [csswg-drafts] [css-view-transitions-2] Extend `waitUntil` so that it can delay the start of the View Transition (animating phase) (#13013)

The CSS Working Group just discussed ``[css-view-transitions-2] Extend `waitUntil` so that it can delay the start of the View Transition (animating phase)``.

<details><summary>The full IRC log of that discussion</summary>
&lt;romain> present-<br>
&lt;andruud3> present-<br>
&lt;andruud3> o/<br>
&lt;dholbert> bramus: a while ago, we resolved on adding a waitUntil method on view transition instance<br>
&lt;dholbert> that lets you delay the view transition from finishing until an extra promise has settled<br>
&lt;dholbert> tim brought up that it's not clear from name that this delays completion<br>
&lt;dholbert> you might think it delays the start of a transition<br>
&lt;dholbert> Good thing is, we sometimes might need to do both things<br>
&lt;dholbert> sometimes you might want to delay the completion; other times you might want to delay the start<br>
&lt;dholbert> right now, to do that, you start a VT, await its ready promise, and then grab all the linked animations and pause them<br>
&lt;dholbert> then await some promise, then unpause all the animations<br>
&lt;dholbert> then the vt gets to start<br>
&lt;dholbert> that workaround is a bit weird, because we added waitUntil to avoid that same hack for the finished promise<br>
&lt;dholbert> (a similar hack was previously how you might do this for finished, before we added waitUntil)<br>
&lt;dholbert> so maybe we should extend waitUntil to let authors specify which phase they care about<br>
&lt;dholbert> syntax could be to extend waitUntil to accept an object, which takes a promise and a phase-specifier<br>
&lt;vmpstr> q+<br>
&lt;dholbert> which would be called back on "ready" or "finished"<br>
&lt;dholbert> which maps to the author-exposed promises<br>
&lt;TabAtkins> q+<br>
&lt;emilio> q+<br>
&lt;dholbert> astearns: are the phases in IRC correct?<br>
&lt;dholbert> astearns: in the example, I see "animating"<br>
&lt;dholbert> astearns: what would the phases be here<br>
&lt;astearns> ack vmpstr<br>
&lt;dholbert> bramus: I see that in the example, I passed in a phase that is spec-internal... need to double-check<br>
&lt;dholbert> vmpstr: I'd like to better understand the prevalence of the use-cases that need this<br>
&lt;dholbert> vmpstr: this is doable but it adds complexity to impls<br>
&lt;dholbert> vmpstr: and authors have options already<br>
&lt;dholbert> vmpstr: e.g. you could style animations to start in a 'paused' state<br>
&lt;dholbert> and then start them when you want with webanimations api<br>
&lt;dholbert> vmpstr: so is this a core use-case or an edge case<br>
&lt;dholbert> bramus: common case is when author wants to delay a VT until an image has loaded<br>
&lt;dholbert> bramus: e.g. in a lightbox<br>
&lt;dholbert> vmpstr: those examples already exist - wait for the image, *then* start the VT<br>
&lt;flackr> ::view-transition { animation-play-state: paused; } .ready::view-transition { animation-play-state: running; } (repeat for each vt animation pseudo)<br>
&lt;astearns> ack emilio<br>
&lt;dholbert> emilio: doesn't the update callback also support returning a promise that would delay the start?<br>
&lt;dholbert> vmpstr: it does, but it has a timeout specified to avoid arbitrary delays<br>
&lt;dholbert> vmpstr: and when you're waiting for network, we try to discourage that<br>
&lt;dholbert> emilio: seems like it could be an option tho?<br>
&lt;dholbert> emilio: this proposal doesn't seem particularly different. This would let you sidestep that timeout<br>
&lt;dholbert> emilio: maybe we add an option to let you remove the timeout?<br>
&lt;dholbert> vmpstr: that's possible... subtle difference is, while the callback is running, you're not producing frames<br>
&lt;dholbert> vmpstr: so there are more implications than just pausing the animation<br>
&lt;dholbert> emilio: I thought that's what this proposal was proposing<br>
&lt;dholbert> vmpstr: only if you're doing a full-screen effect, animating on root etc<br>
&lt;dholbert> vmpstr: but if you just pause animations associated with a smaller VT, rendering would not stop<br>
&lt;dholbert> emilio: bramus can you clarify the intended semantics around start .... or maybe I'm misunderstanding<br>
&lt;astearns> ack TabAtkins<br>
&lt;dholbert> vmpstr: FWIW I think removing the timeout and extending the callback is a viable approach to address this use-case; it's just got different tradeoffs than waitUntil<br>
&lt;dholbert> TabAtkins: small note... for the proposed signature, we shouldn't do a choice of a promise or an object-holding-a-promise<br>
&lt;dholbert> TabAtkins: in IDL, a promise type argument accepts anything<br>
&lt;dholbert> TabAtkins: The options arg needs to be an optional 2nd arg<br>
&lt;astearns> ack dbaron<br>
&lt;Zakim> dbaron, you wanted to mention 2-argument syntax alternative<br>
&lt;dholbert> dbaron: I was gonna say the same thing as TabAtkins, because it seems more readable as a syntax<br>
&lt;bramus> q+<br>
&lt;astearns> ack bramus<br>
&lt;dholbert> bramus: Regarding the "animating" phase in the github example<br>
&lt;dholbert> bramus: that's correct, we want to delay the animation until the specific promise has resolved<br>
&lt;dholbert> bramus: so the VT is in its ready state, and waiting to start the animations until a promise has resolved<br>
&lt;dholbert> astearns: maybe we don't need to add more syntax for this?<br>
&lt;dholbert> bramus: historically we added waitUntil to make this easier at finished time<br>
&lt;dholbert> bramus: odd that we'd force them to do the hack at start time<br>
&lt;emilio> q+<br>
&lt;dholbert> astearns: any concerns with resolving to do this?<br>
&lt;astearns> ack emilio<br>
&lt;dholbert> emilio: I really want to clarify what the semantics of different phases would be<br>
&lt;dholbert> emilio: seems like it wouldn't be equivalent to just a long-running update callback<br>
&lt;dholbert> bramus: one scenario: you could kick off a fetch to get some data<br>
&lt;dholbert> bramus: then start some VTs<br>
&lt;dholbert> emilio: so it's like a pre-delay...<br>
&lt;dholbert> bramus: ...before the animations start playing<br>
&lt;dholbert> emilio: so right now, you call startVT with an async function<br>
&lt;dholbert> emilio: and that delays it, and you block rendering and await some stuff<br>
&lt;dholbert> bramus: and you can see that your page is visually frozen<br>
&lt;dholbert> bramus: whereas if you kick it off and let some stuff happen but hold off the start of the animations playing until promise was settled... it's better<br>
&lt;dholbert> vmpstr: compared to kicking off the fetch first, and when that resolves you start the view transition.,.. you've saved the capture phase<br>
&lt;dholbert> vmpstr: and that's 1.5 animation frames in Chromium that we're trying to optimize<br>
&lt;dholbert> vmpstr: so this doesn't buy you much<br>
&lt;dholbert> vmpstr: you're separating the start of a vt to not-yet-animate<br>
&lt;dholbert> vmpstr: which is a distinction we don't need to have<br>
&lt;dholbert> emilio: so the VT ready promise , which does the snapshot... that would run, then ready would resolve, then the animations are paused until the waitUntilTHing resolves?<br>
&lt;dholbert> bramus: yup<br>
&lt;dholbert> vmpstr: so you're saving the callback running time<br>
&lt;dholbert> vmpstr: but the case that you've presented, you want to fetch some resources first<br>
&lt;dholbert> vmpstr: and the callback to update those resources would typically be quick, just updating your HTML or whatever<br>
&lt;dholbert> vmpstr: so this doesn't feel like a performance or ergonomic win<br>
&lt;dholbert> vmpstr: as compared to flipping the order of fetch and startVT<br>
&lt;dholbert> emilio: feels a bit confusing. If I were to delay startVT, I'd expect the same behavior as a long-running callback<br>
&lt;dholbert> emilio: but you're trying to ...<br>
&lt;dholbert> bramus: so vmpstr is saying to do the fetch first and wait for that to be settled before kicking off the VT<br>
&lt;dholbert> emilio: yeah, and don't you want the resource to be ready at the start of the VT?<br>
&lt;dholbert> bramus: I came up with the image-loading use-case, cross-document VTs where you click on one page into detail page, and you want the image to load<br>
&lt;dholbert> bramus: and if you use blocking=render on the img tag, then it blocks rendering until the parser sees the image, *not* until the image has acctually loaded<br>
&lt;dholbert> bramus: so for the MPA case, in your pageReveal function, there you want to kick off the loading of the actual big image, and hold off the VT from running, and then once the image has loaded, you let it run<br>
&lt;dholbert> emilio: is that blocking=render behavior... does that match what we do for &lt;link>?<br>
&lt;dholbert> emilio: if I do it with link, I expect the stylesheet to load<br>
&lt;dholbert> emilio: if img doesn't do that, that seems bad?<br>
&lt;dholbert> vmpstr: I think render-blocking only blocks until parsing of the element, not the external resource fetch<br>
&lt;dholbert> emilio: for styles, that seems bad?<br>
&lt;dholbert> bramus: don't styles already do that?<br>
&lt;dholbert> emilio: not if you do them via script<br>
&lt;dholbert> astearns: maybe we should wrap up this issue to sort out use-cases and proposed behavior<br>
&lt;dholbert> emilio: yeah. e.g. for cross-document case, you're not blocking the update callback<br>
&lt;dholbert> bramus: it already happened, you already navigated<br>
&lt;dholbert> emilio: so it's more of a pause-until than wait-until<br>
&lt;dholbert> astearns: let's take it back to the issue<br>
&lt;dholbert> astearns: need a bit more justification<br>
</details>


-- 
GitHub Notification of comment by css-meeting-bot
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/13013#issuecomment-3819860178 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Thursday, 29 January 2026 19:34:56 UTC