- From: CSS Meeting Bot via GitHub <sysbot+gh@w3.org>
- Date: Tue, 01 Apr 2025 17:32:05 +0000
- To: public-css-archive@w3.org
The CSS Working Group just discussed `[css-animations-2] Add declarative syntax for starting an animation in response to an input event`. <details><summary>The full IRC log of that discussion</summary> <TabAtkins> szager: This is very rough sketch, not prepared to depend every details<br> <TabAtkins> szager: responsiveness is important part of good perf, always a struggle<br> <TabAtkins> szager: big part is input events require main-thread processing<br> <TabAtkins> szager: if you're familiar with Core Web Vitals, something we emphasize is interaction to first paint<br> <TabAtkins> szager: looking at IMP measurements in the wild, at higher percentiles main-thread processing >50% of that first response delay<br> <TabAtkins> szager: so we want to solve, how can we provide visual repsonse to input events without main thread processing<br> <TabAtkins> szager: so i think this proposal is in-line with compositor-driven animations<br> <TabAtkins> szager: we set up the animation in advance then hand it off to the compositor<br> <TabAtkins> szager: i'll say, my terminology is chrome-specific but i think the principles apply to everyone, they'll be implementable for everyone<br> <TabAtkins> szager: so we create an animation on the main thread, then trasnfer it to compositor thread if possible, and it can run smoothly after that<br> <TabAtkins> szager: in that spirit, we shoudl be able to do that (set up in advance) but rather than a time delay, say we'll start when we detect an input event<br> <TabAtkins> szager: currently in web platform, input events are only dete3ctable on main thread<br> <TabAtkins> szager: but this declarative syntax lets us analyze that and enact that on the compositor thread before it even hits the main thread<br> <TabAtkins> szager: so the result is we cut out the main-thread processing entirely when we start processing an input event<br> <TabAtkins> szager: big risk up front - this is a predictive model, like thread scrolling or composited animations<br> <TabAtkins> szager: we're predicting that, if the main thread weren't blocked, it would say we shoudl run this animation. this can be wrong - the main thread might try to cancel it but it's blocked<br> <TabAtkins> szager: in composited animations, the downside of the prediction being incorrect isn't important<br> <TabAtkins> szager: in this it could be a bit more consequential<br> <TabAtkins> szager: someone could click on something, animation starts immediatley suggesting the click was received<br> <astearns> q+<br> <TabAtkins> szager: and then eventually when we flush the rendering and actually deal with the input, it could just stop<br> <TabAtkins> szager: could be weird for the user to see this inconsistent animation<br> <TabAtkins> szager: so that's biggest risk i think. should keep our eyes on it<br> <TabAtkins> astearns: couple question<br> <TabAtkins> astearns: are you at all worried about having multiple things trigger off of a user interaction, and have the animation kick off long before any secondary effects on the main thread?<br> <astearns> ack astearns<br> <flackr> q+<br> <smfr> q+<br> <TabAtkins> szager: at least for chrome, our devrel, we always push to give a visual response asap<br> <TabAtkins> szager: so our guidacne is to start the animation *immediately*, and only once that's actually running should you do your business logic<br> <ydaniv> q+<br> <TabAtkins> szager: so there's always a risk that main-thread processing will invalidate what we're starting. This isn't a replacement for main-thread handling.<br> <TabAtkins> szager: we're just taking that first step (kick the animation immediatley) and making it declarative<br> <TabAtkins> szager: so the rest of the model is the same<br> <TabAtkins> astearns: that's helpful<br> <TabAtkins> astearns: the other thing is, a concern about having some user events with this preemptive animation, and other where they're not<br> <TabAtkins> astearns: there are several user inputs in a row, some trigger fast and others are slow, and the reaction to user events is out of order<br> <astearns> ack flackr<br> <TabAtkins> flackr: in case people ahven't recognized this, thi si sperfectly analogous to scrolling<br> <TabAtkins> flackr: in that you can set up a scroll on the compositor that is invalidated by a scrollTo in the next frame<br> <TabAtkins> flackr: so it's not new, and i think this is a reasonable explanation<br> <TabAtkins> flackr: some more cmplications tho<br> <TabAtkins> flackr: some event types are only generated if other types aren't preventDefaulted<br> <TabAtkins> flackr: like click can be canceled by down/up<br> <TabAtkins> flackr: so we need to either restrict to primary events, or do something else<br> <TabAtkins> flackr: also, the user interacts with what they see, they're not in the new frame yet<br> <TabAtkins> flackr: so this does feel better. i click on what i see, th enext frame can certainly move it or whatever, but maybe we should do hit testing in the frame the user is seeing rather than the positions that dom modifications see<br> <TabAtkins> flackr: maybe we should explore that<br> <TabAtkins> szager: the idea of doing event hit testing based on last displayed content has been proposed a millino times, it's a can of worms.<br> <TabAtkins> szager: i like the idea, but it's a breaking change<br> <TabAtkins> szager: but that's the only thing i don't like about it. in every other respect it's better i think.<br> <TabAtkins> szager: don't know that i want to conflate that with this project tho<br> <TabAtkins> szager: other point about non-primary events<br> <TabAtkins> szager: the reason we can do this project in chrome is events arrive on compositor before they hit the main thread<br> <TabAtkins> szager: but we only have limited insight into the input targetting<br> <TabAtkins> szager: our hit-testing is non-canonical<br> <TabAtkins> szager: so like we can't do a strict determination fo the event target until we hit the main thread<br> <TabAtkins> szager: so that's a source fo inaccuracy<br> <TabAtkins> szager: part of this project would be to see ho wmuch more hit-testing capability we need to add to our compositor thread<br> <TabAtkins> szager: and think it would be a simlar process for other browsers<br> <TabAtkins> szager: end-gaem of that process is doing precise hit-testing on compositor thread from the msot recently displayed content<br> <TabAtkins> szager: so it's in that arena. dont' wanna commit to that huge breaking change now, but want to explore that some<br> <TabAtkins> flackr: secondary events are not sent to the compositor, they're generated in blink as part of primary event<br> <TabAtkins> flackr: we'd need to add special processing, compositor only see mouseup/mousedown, we synthesize click on main<br> <TabAtkins> szager: i think chrome could do this, yes. no hard proposal yet. question is how much functionality do we need on the compositor.<br> <TabAtkins> flackr: my point is, we always have the option to say some event types are triggered on main<br> <TabAtkins> szager: i'll say, this proposal doesn't need to involve compositor thread. as-is it could be done entirely on the main thread<br> <TabAtkins> szager: the compositor is an optimization. it's the point of this feature, yes, but it could just run on the main<br> <TabAtkins> szager: so we can start from the baseline of makign it work right without compositor optimizations<br> <TabAtkins> szager: and then this is a predictive model, we find as many scenarios as possible that we can do on the compositor. can't define the boundary yet, and it probably changes over time, and could vary between brwosers<br> <TabAtkins> szager: but i think the design of the api, i always kept in mind making it possible to add the optimizations after the fact<br> <TabAtkins> flackr: i think we agree<br> <TabAtkins> flackr: hit-testing on the previously-seen thing is something that gives consistency with what the user sees and what they expect<br> <TabAtkins> flackr: so i think it does make sense exploring<br> <TabAtkins> szager: i agree in every state except compat. so if this is a compat anchor i don't want to be tied to it.<br> <astearns> ack smfr<br> <TabAtkins> smfr: this feels more consequential than scrolling as to getting it wrong.<br> <TabAtkins> smfr: you can't do precise hit-testing, and aren't running inputs properly<br> <TabAtkins> smfr: so you dont' know if something else canceled<br> <TabAtkins> smfr: this is important for things like iframes<br> <TabAtkins> szager: in chrome we do do precise hit-testing for iframes<br> <TabAtkins> smfr: in webkit, if there's a clip path overlapping the iframe, we can't do precise hit-testing on our compositor<br> <TabAtkins> smfr: so you say we kick it off on the compositor and then cancel it if the real event doesn't fire<br> <TabAtkins> smfr: so what happens with animation events?<br> <TabAtkins> szager: we wont' fire animation events until animation start has been affirmed on the main thread<br> <TabAtkins> szager: so no ordering changes<br> <flackr> qq+<br> <TabAtkins> szager: one place that might look different is start time, but in terms of order animationStart event happens at normal position<br> <TabAtkins> szager: i agree with everything you're saying about iframe security/etc<br> <TabAtkins> szager: so i'll point back to, this can be done on the main thread.<br> <TabAtkins> szager: we considered a broader syntax, but decided to keep it narrow and just use animation-trigger to keep it simple<br> <TabAtkins> szager: so can do it all on main, then judiciously move to compositor thread<br> <astearns> ack flackr<br> <Zakim> flackr, you wanted to react to smfr<br> <TabAtkins> flackr: we can pick and choose the precise cases where we're completely or reasonably confident that we have the target correct and it wont' be stopped<br> <TabAtkins> flackr: so it's possible to do it in a way that's correct save for extreme dom modification<br> <TabAtkins> szager: it's true that compositor hit testing isn't authoritiative, but in chrome the compositor thread is aware *when* it's not authoritative<br> <TabAtkins> szager: then we defer to the main thread, like if there's a clip path<br> <TabAtkins> szager: so if there's an important decision to be made, we can push off the optimization. hopefully others can too.<br> <astearns> ack ydaniv<br> <TabAtkins> ydaniv: this sounds very interesting<br> <TabAtkins> ydaniv: i was also worried about what simon mentioned, regarding stopPropagation, but if it's considered then good<br> <TabAtkins> ydaniv: had a lot of questions about api<br> <TabAtkins> ydaniv: but most important is probably 3rd question i wrote on the issue<br> <TabAtkins> ydaniv: this is also very desired with transitions, but then it's not thru animation api but thru selectors<br> <TabAtkins> ydaniv: that maybe goes back to css toggles, which is sorta deceased<br> <TabAtkins> ydaniv: wonder if this is something we coudl marry with a state pseudoclass<br> <TabAtkins> szager: one of our early ideas was a pseudo-state<br> <TabAtkins> szager: we went thru it and the difficulty... it's probably most similar to :active<br> <TabAtkins> szager: but looking deep into it, we don't know where the start/stop of the pseudo-state is.<br> <TabAtkins> szager: this is a discrete event, not a toggle back and forth between two states<br> <TabAtkins> szager: can't just analyze the dom and styels and say "we know we're in this state". it's ephemeral and it's gone<br> <TabAtkins> szager: so it just doesn't seem to be a good match to pseudo-states, anything toggleable<br> <TabAtkins> szager: this isn't even like viewport visibility, where you're either in or out. this is immediate.<br> <TabAtkins> szager: i foudn the best mental model is element.getAnimations.play(), like that. once that line is executed, you can't detect that it happened, you just know the animation is now playing. no idea how it started.<br> <TabAtkins> szager: so just the idea of a state that toggles on or off doesn't seem to be the right model for this<br> <TabAtkins> ydaniv: so this moves to the second question, if this state is transient, how will this work with different types of triggers?<br> <TabAtkins> ydaniv: there we have "alternate" types... the state is in the animation then<br> <flackr> qq+<br> <TabAtkins> szager: right, i think if the state is the namation state, you can pause/play from there<br> <TabAtkins> szager: if you explicitly call .play() on the animation, the input event could pause that animation<br> <astearns> ack flackr<br> <Zakim> flackr, you wanted to react to ydaniv<br> <astearns> zakim, close queue<br> <Zakim> ok, astearns, the speaker queue is closed<br> <TabAtkins> flackr: having thought a lot about animatin-trigger, they have a thing that happens when the triggered state goes from outsdie->inside or reverse. i think each occurence of a discrete event woudl be a transition similarly.<br> <TabAtkins> flackr: and what the trigger does depends on what trigger's state. "state" woudl pause/unpause, "alternate" would play it backwards/forwards, etc. each has a defined meaning already<br> <TabAtkins> szager: yeah, since triggers are defined in terms of transition events, it works cleanly with inputs as long as the state lives in the animation<br> <astearns> ack pdr<br> <TabAtkins> flackr: right. currnently it's a state transition that toggles it, but that's not required<br> <TabAtkins> pdr: quick comment on original question,a bout mixing fast and slow properties<br> <TabAtkins> pdr: animation lets us build on the existing infrastructure<br> <TabAtkins> pdr: if you ahve a layout-affecting property in an animation, it can already pull the whole animation out to main thread<br> <TabAtkins> pdr: with animations you define up front the things that are affected, while with selectors it's open-ended<br> <TabAtkins> pdr: so i think animation approach works iwthin those problems<br> <TabAtkins> astearns: thank you for the introduction, let's flesh out the details more<br> <astearns> zakim, open queue<br> <Zakim> ok, astearns, the speaker queue is open<br> </details> -- GitHub Notification of comment by css-meeting-bot Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12029#issuecomment-2770201223 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Tuesday, 1 April 2025 17:32:06 UTC