-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Requirements and usage of the SPA API #189
Comments
Maybe I'll share a few thoughts, just from my perspective
There's an added wrinkle here that "capturing" is as either single snapshot or can be flattened into a series of non-overlapping elements (is that right?). And that the transition between those two states (before/after) can be represented as a transform between those two images.
And that the page is responsible for making sure it is largely static until that snapshot is taken. Existing animations or other UI changes need to be paused, waited, or finished.
I do think it would be good to be more specific about the expectations for how long it should really take to update the DOM. I think there's also some expectation in the API that longer work (like network requests) that are necessary to perform the transition should probably be done before the transition even begins. Making an API async can sometimes invite people to think that it's an opportunity for them to take as long as they need, but really I think the intention with making it async is that your work is resolved within a few microtasks, perhaps.
This I think is perhaps a little controversial, and I would actually expect that most SPA transitions today do NOT abort on an uncaught error. I would suggest relaxing this a bit, or at least make it up to the user what should and shout not abort the transitions as far as errors. There will be some cases where an Error indicates a complete failure, but there are others that might be completely benign. I think it's really only possible to determine whether a DOM change fails or not from the page itself, I don't think the browser has enough certainty to determine that.
I think this gets more complicated with MPA where you might not have full control over the next page, but would still want something reasonable for your transition out. I think there will probably be SOME misconfigurations that do not completely abort the transition and are recoverable.
Yeah, but just highlighting that it's up to the page whether a new transition should preempt an existing DOM change or do the DOM change immediately. This gets more complicated if DOM changes are async... again encouraging people to make their DOM changes short. -- I think the API requires that the page knows basically exactly what the page looks like before and after the transition, and just wants to add some easy animation between those states. I think when people read this proposal, they may think that it aims to be something more than it is. If I had to describe this API, it's "if your page changes quickly from one DOM structure to another, you can add an easy animation to make that transition". It is not "we aim to provide browser support for the full view transition lifecycle." I think where confusion creeps in is that the API shape seems to imply that it is more concerned with lifecycle than it actually is - I think people who have nuance about transitions (different styles of abort, etc), DOM changes that are long, or any uncertainty about what the page will look like after the transition, should not use this API. |
This issue isn't really dealing with the CSS side of things, it's more about how the developer interacts with the JS API. The explainer has details on the capturing, and there are further details in the spec.
Maybe? Sites don't generally delay navigations on animations finishing, so an abrupt pause of the outgoing state might be ok in many situations.
Correct. There are two parts to this solution:
That is controversial! It would clash with other APIs that follow a similar pattern, such as the Navigation API, and the Web Locks API. The rough steps are:
Step 2 is given to the developer, via the I think it would be a real mistake to take this "something went badly wrong" signal and assume "ah well it's probably ok".
That's already possible: document.createTransition({
async updateDOM() {
try {
await framework.performDOMUpdate();
} catch (err) {
// just swallow all errors
}
},
}); That means that transitions would apply to potentially broken content, but hopefully it would be clear to the developer that they were intending that by obscuring the "it went wrong" signal.
Right. That's why the API leaves it to the developer to return that signal.
This issue is focusing on the SPA API. For the MPA API I still think we should fail on misconfiguration in either of the captures, but yes it's harder to confirm compatibility between the two. My current thinking is to allow a clonable object to be passed from the outgoing to incoming page, and I'd recommend developers use some sort of versioning scheme to bail the transition if they have a low confidence that the two pages can transition in a meaningful way.
I think that's right. The transition 'wraps' a DOM change. But I think developers will frequently make that DOM change without the transition API (either due to a browser not-supporting the transition API, or they want to avoid it due to user preference). So, the transition API should be about transitions only. It shouldn't provide scheduling features beyond that.
Yeah, the feature is kinda tangled with the DOM change. A navigation fails if the DOM change fails. A navigation doesn't fail if the transition fails. However, the transition 'wraps' the DOM change, since it should fail if the DOM change fails. The
I don't think that's the right conclusion. I think the correct conclusion is: Developers shouldn't build transitions that require more certainty about the content than they have. Eg, they shouldn't create a transition that assumes both states have a header, if they're not certain both states have a header. In that case they should either build a transition that can deal with the header existing in both states, one state, or neither state, or don't try to do anything special with the header. Simpler transitions, such as a cross-fade, don't require much certainty between the two states. "Don't act with certainty if you're not certain" seems like basic sense to me, but maybe I'm too deep in this. |
I chatted the API through with @surma, and here's the feedback: It's mostly intuitive that:
Stuff that was less clear: In the case of: const transition = document.createTransition({
async updateDOM() {
await coolFramework.setState(stuff);
}
});
const transition = document.createTransition({
async updateDOM() {
await coolFramework.setState(otherStuff);
}
}); …it wasn't clear whether the transition should be from the state when Some feeling that
Most of the disagreement with the current API is around
|
This was a misunderstanding on my part of what you meant by an Error being thrown. You mean specifically an Error being thrown in the updateDOM callback? I thought you meant any page level Error at all during a transition. My expectation is that other JS will continue to run outside the updateDOM callback. But yeah, makes sense.
Is there a way to access the global list of active transitions or do you have to keep track of them yourself?
My assumption is that by default transitions queue, first come first serve, and the DOM change is uncancellable via the transition API itself?
Consider as an alternative if people aren't really paying attention to the rejected value of ready to do anything: const transition = document.createTransition({
async updateDOM() {…}
beforeTransition() {}
}); If the only use case for observing const transition = document.createTransition({
async updateDOM() {…}
});
transition.addEventListener('beforeTransition', () => {});
What's the use case for knowing if an animation ran or not? I agree that finished is most useful as "the dom is changed and the animation is settled". Finished resolving to a value is alright. |
Re-iterating some things we discussed in a private chat: Solving it might be a matter of naming bikeshedding, perhaps: const transition = document.createTransition({ async updateDOM() { ... });
// Rejects if animation cannot be performed
transition.readyToAnimate : Promise<void>
// Rejects if the animation was skipped or not performed for some reason
transition.animationComplete : Promise<void>
// Always resolves once the animation is completed or skipped
transition.finished : Promise<void>
// Rejected only if `updateDOM` throws an exception, otherwise resolved when DOM updates are applied
transition.domUpdated : Promise<void>
// Fast forwards the animation and completes the transition immediately
transition.finish() : void |
No, but I think we'll need something like that in future. If we end up allowing transitions to be limited to a particular element, it creates a situation where:
…but otherwise, two transitions can happen in parallel. Given this, the queuing system will need some thought to get right.
Yeah, I've had similar thoughts (but just called it
The use-cases I can think of are logging (are animations unexpectedly not-finishing?), and "I want my transition to run after the current transition, but if the current transition skips, mine should also skip". |
A couple of folks said the API is confusing in parts. Maybe it can be improved. As a basis for the conversation, here are the current assumptions:
page-transition-tag
), the transition shouldn't happen. This may be detected before the DOM change, but it shouldn't prevent the DOM change.The current API:
updateDOM
- this is where the developer changes the DOM. The callback allows the feature to know when the DOM change is complete (via the returned promise) and rejections indicate failure. This callback is always called, as the DOM update is more important than the transition.domUpdated
- this exposes the result ofupdateDOM
for use in other APIs, such as the navigation API. It may fulfill even if the transition is skipped, or cannot happen due to misconfiguration.ready
- this fulfills when the transition is ready to go, so parts of the animation can be driven with JS. It rejects if the transition fails to become ready, due to skipping, misconfiguration, or a failure in the DOM change.finished
- this fulfills when the transition animates to completion. It rejects if the transition fails to fully finish, due to skipping, misconfiguration, or a failure in the DOM change.skipTransition()
- causes this transition to end abruptly, and rejectsready
andfinished
if they haven't already resolved.The text was updated successfully, but these errors were encountered: