-
Notifications
You must be signed in to change notification settings - Fork 19
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
"deadline" in the "start an idle period algorithm" should be defined in terms of event loop #71
Comments
I think this is best resolved by hooking into the HTML event loop spec as is being discussed in #70 |
So seems like this is blocked on #70 |
@rmcilroy Would landing whatwg/html#4104 fix this issue as well? Or is there extra work to be done here? |
No, we still need to define what it means for the event loop to be idle. The issue I raised is that just because this particular global object doesn't have any active timers, it doesn't mean other global objects such as those of iframe don't have a bunch of active timer soon to be fired. So this deadline needs to be computed the same way whatwg/html#4104 defines the timing at which this algorithm is invoked. |
Right, this would need more work. It's not entirely clear how we could spec this - the current spec for setTimeout / setInterval relies on "wait for timeout milliseconds in parallel" before queuing a task on the task queue, so there isn't actually anything queued anywhere while the timer is pending that we could surface to the rIC algorithm. Any thoughts? |
How is it implemented? Can we use that as inspiration for the spec? |
In Chrome the delayed tasks are posted on a task queue while they are pending, ordered by their timeout/delay (this includes internal tasks as well as setTimeout tasks). We set the deadline to be the time of the earliest task in the queue (and also cap to 50ms or next frame deadline if we are rendering). |
This is pretty much how we do it in Gecko as well. |
It seems like modifying the HTML spec to accommodate this would be a decently big effort, and actually thinking about it I'm not sure how much it helps given the spec also wants to let the UA shorten the deadline earlier for internal tasks as well as those posted via the HTML spec, and to use heuristics to predict the likelyhood of an external event happening during that time. I.e.:
How about moving the discussion of the setTimeout, etc. to a non-normative note, and make the normative section explicitly regarding the event loop, i.e.: Let deadline be a time in the future until which the UA expects the window's event loop to remain idle. The user agent SHOULD choose deadline to ensure that no time-critical tasks will be delayed even if a callback runs for the whole time period from now to deadline. Note: Typically the deadline should be set to the minimum of: the closest timeout for the list of active timers as set via setTimeout and setInterval to the window's event loop; the scheduled runtime for pending animation callbacks posted via requestAnimationFrame; pending internal timeouts such as deadlines to start rendering the next frame, process audio or any other internal task the user agent deems important. WDYT? |
@rniwa friendly ping! :) |
Again, my main issue with the spec is that this isn't precisely defined. Adding a non-normative note wouldn't cut it. In general, if the spec doesn't meet the bar of specifying a feature to the extent it should, then the right call is to delay the publishing of the spec instead of hand-waving the definition of it. We can't spec a deadline by enumerating examples. That precisely is the current spec's wording I have an issue with. And, again, "given browsing context's event loop" doesn't make sense because the event loop is a global concept shared across a unit of related browsing contexts. |
Fair enough, would someone be willing to add the necessary hooks into the HTML spec to make this happen? I don't have the bandwidth or experience with the HTML spec to do that at present. |
Going back to this, and since the definition of "deadline" should also include heuristics regarding external events (which we don't intend to specify), I'm not sure what the benefits of specifying that would be. @rniwa - are there any compatibility issues that you think will arise from keeping this value UA defined? |
Obviously. You can have a timer inside an iframe or a window then the deadline according to the current spec would be ignoring that. It's true that we can observe what Blink and Gecko had implemented and not make such a stupid mistake but the purpose of the spec is to clarify what needs to be implemented even in absence of any implementation. If we're forced to reverse engineer what Blink and Gecko did to implement this in WebKit, what the heck is the point of having this spec at all? |
I believe the case of same-origin iframe or window are covered by the suggested normative language @rmcilroy suggested. Specifically, "Let deadline be a time in the future until which the UA expects the window's event loop to remain idle. " covers that case, as same-origin iframe or window share an event loop with the window. Otherwise, I don't think that there will be benefits to defining UA-specific, internal events as part of the spec and it's better to keep them vague, to enable better flexibility when it comes to such heuristics. That leaves us with the issue of timers. Timers do not currently queue tasks immediately, but only after the timer expired. They do register themselves on the "list of available timers", but that list is separate per global scope, even if multiple global scopes share an event loop. So, maybe we can extend the suggested normative language and replace the current reference to timers of "the closest timeout in the list of active timers" with "the closest timeout in the list of active timers in any global scope that queues tasks on window's event loop". Thoughts? |
That wording would work if we can define what it means for an event loop to remain idle. Let's consider the following clause in the event loop processing model which defines when to start an idle period algorithm:
This definition makes it crystal clear as to exactly what condition constitutes the start of an idle period and when the algorithm is invoked relative to all other things happening in the browser. We need something similar. We need exactly what remain idle means. Is it that we don't expect a task/microtask to be scheduled in the current event loop? Is it that the rendering opportunity won't be happening? etc... As for timers, yeah, we probably need to define the time at which the next/closest timeout from the list of active timers of each document of the browsing contexts which use the same event loop as a given window's browsing context. |
Here is a list of things we discussed during F2F to explicitly list instead of "expect to remain idle"
|
Now that the HTML spec has explicit task sources when queuing tasks from algorithms that run in parallel, maybe can tie the concept of deadline to that. In particular, maybe we can say the deadline is reached when a new task is being queued to the user interaction task sources? |
/cc @spanicker @shaseley - opinions on #71 (comment)? |
That wouldn't address the timer issue, right? It would address user input preempting an idle period, though and seems sensible in that regard. It wouldn't be able to affect the deadline calculation, though, unless I'm missing something. |
@bzbarsky : Right, we have to handle the timer timeouts separately from the user inputs. So my straw man proposal for when the deadline becomes 0 is as follows:
|
So there are two meanings of "deadline", right?
That proposal works for item (2), but I don't see how item (1) can depend on "The time at which the user interaction task source gets a new task enqueued", because that time is not known when the call happens, right? |
@bzbarsky : Right. I think (1) will depend on timers & rAF for now. We can add more things to the list as we find them. |
Right, for (2) we already have a hook in the step 4 of the IdleDeadline timeremaining() interface to set it to zero if a "time-critical task pending". I agree we could use the new user interaction task source to make this phrasing more precise. |
As I mentioned in #78, I don't think the phrase "time-critical task" would be any more precise than arbitrary time UA picks since there is no definition for being time critical. |
That's why I suggested changing that phrasing to be based on the new new user interaction task source. |
Per today's meeting, we tentatively agreed to define the deadline to be the minimum / earliest of:
|
We should modify timer initialization steps to define the time at which each timer fires because there is no such a thing defined right now. In particular, the timeout only progresses while the document is fully active so that means it's not a simple wall clock or monotonic time that we can calculate. It's possible for a timer in one document to not expected to fire because the timeout doesn't progress due to the document not being fully active. |
The algorithm replaces the algorithm that is currently defined in prose here: https://w3c.github.io/requestidlecallback/#the-idledeadline-interface). It works as such: - Timers can calculate their estimated next callback timestamps, based on their start time and document-inactive time so far. - The deadline for idle tasks for an event loop is the earliest between: - The time until the next timer callback in this event loop is estimated to fire. - The time until the next render, estimated at16ms after the start of the previous task that had a rended opportunity, if there are pending requestAnimationFrame callbacks. - 50ms TODO: the deadline is currently checked between windows, it needs to be re-checked between callbacks in the same window. See w3c/requestidlecallback#71
In conjunction with whatwg/html#7166 Instead of defining the idle period deadline in prose, rely on the event model processing in the HTML spec to provide a more precise computation of the current idle period deadline. This is accomplished by passing a `getDeadline` algorithm from the HTML spec to this spec when starting an idle period, and re-computing that deadline between idle callbacks, or when `timeRemaining()` is called. This ensures (more formally) that adding timeouts that expire before the end of the idle period, or `requestAnimationFrame` calls from within the idle period, which currently are specified to fire before the next idle tasks due to event loop priorities, will also be reflected when calling `timeRemaining`. Closes #71
The algorithm replaces the algorithm that is currently defined in prose here: https://w3c.github.io/requestidlecallback/#the-idledeadline-interface). It works as such: - Timers can calculate their estimated next callback timestamps, based on their start time and document-inactive time so far. - The deadline for idle tasks for an event loop is the earliest between: - The time until the next timer callback in this event loop is estimated to fire. - The time until the next render, estimated at16ms after the start of the previous task that had a rended opportunity, if there are pending requestAnimationFrame callbacks. - 50ms TODO: the deadline is currently checked between windows, it needs to be re-checked between callbacks in the same window. See w3c/requestidlecallback#71
The algorithm replaces the algorithm that is currently defined in prose here: https://w3c.github.io/requestidlecallback/#the-idledeadline-interface). It works as such: - Timers can calculate their estimated next callback timestamps, based on their start time and document-inactive time so far. - The deadline for idle tasks for an event loop is the earliest between: - The time until the next timer callback in this event loop is estimated to fire. - The time until the next render, estimated at16ms after the start of the previous task that had a rended opportunity, if there are pending requestAnimationFrame callbacks. - 50ms TODO: the deadline is currently checked between windows, it needs to be re-checked between callbacks in the same window. See w3c/requestidlecallback#71
The algorithm replaces the algorithm that is currently defined in prose here: https://w3c.github.io/requestidlecallback/#the-idledeadline-interface). It works as such: - Timers can calculate their estimated next callback timestamps, based on their start time and document-inactive time so far. - The deadline for idle tasks for an event loop is the earliest between: - The time until the next timer callback in this event loop is estimated to fire. - The time until the next render, estimated at16ms after the start of the previous task that had a rended opportunity, if there are pending requestAnimationFrame callbacks. - 50ms TODO: the deadline is currently checked between windows, it needs to be re-checked between callbacks in the same window. See w3c/requestidlecallback#71
The algorithm replaces the algorithm that is currently defined in prose here: https://w3c.github.io/requestidlecallback/#the-idledeadline-interface). It works as such: - Timers can calculate their estimated next callback timestamps, based on their start time and document-inactive time so far. - The deadline for idle tasks for an event loop is the earliest between: - The time until the next timer callback in this event loop is estimated to fire. - The time until the next render, estimated at16ms after the start of the previous task that had a rended opportunity, if there are pending requestAnimationFrame callbacks. - 50ms TODO: the deadline is currently checked between windows, it needs to be re-checked between callbacks in the same window. See w3c/requestidlecallback#71
The algorithm replaces the algorithm that is currently defined in prose here: https://w3c.github.io/requestidlecallback/#start-an-idle-period-algorithm. It works like so: * Timers can calculate their estimated next callback timestamps, based on their start time and document-inactive time so far. * The deadline for idle tasks for an event loop is the earliest between: * The time until the next timer callback in this event loop is estimated to fire. * The time until the next render, estimated at 1000 ms / refresh rate after the start of the previous task that had a rendering opportunity, if there are pending animation frame callbacks (or if the user agent believes a render is coming). * 50ms The deadline computation is passed as a set of algorithm steps to the requestIdleCallback() spec, so that it can always return the up-to-date deadline. Helps with w3c/requestidlecallback#71.
The algorithm replaces the algorithm that is currently defined in prose here: https://w3c.github.io/requestidlecallback/#start-an-idle-period-algorithm. It works like so: * Timers can calculate their estimated next callback timestamps, based on their start time and document-inactive time so far. * The deadline for idle tasks for an event loop is the earliest between: * The time until the next timer callback in this event loop is estimated to fire. * The time until the next render, estimated at 1000 ms / refresh rate after the start of the previous task that had a rendering opportunity, if there are pending animation frame callbacks (or if the user agent believes a render is coming). * 50ms The deadline computation is passed as a set of algorithm steps to the requestIdleCallback() spec, so that it can always return the up-to-date deadline. Helps with w3c/requestidlecallback#71.
The algorithm replaces the algorithm that is currently defined in prose here: https://w3c.github.io/requestidlecallback/#start-an-idle-period-algorithm. It works like so: * Timers can calculate their estimated next callback timestamps, based on their start time and document-inactive time so far. * The deadline for idle tasks for an event loop is the earliest between: * The time until the next timer callback in this event loop is estimated to fire. * The time until the next render, estimated at 1000 ms / refresh rate after the start of the previous task that had a rendering opportunity, if there are pending animation frame callbacks (or if the user agent believes a render is coming). * 50ms The deadline computation is passed as a set of algorithm steps to the requestIdleCallback() spec, so that it can always return the up-to-date deadline. Helps with w3c/requestidlecallback#71.
Right now, The start an idle period algorithm defines the deadline as:
However, the list of active timers is defined in terms of a global object. I don't think that's the intent here. It needs to be defined in terms of the event loop. Perhaps we need a list of active timers for the entire event loop to be defined in the HTML specifications itself.
The text was updated successfully, but these errors were encountered: