From e63caefca6b3b76a77b94905a9230ebfdade48f7 Mon Sep 17 00:00:00 2001 From: Noam Rosenthal Date: Thu, 7 Oct 2021 08:06:05 +0300 Subject: [PATCH] Rely on HTML spec for deadline computation In conjunction with https://github.com/whatwg/html/pull/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 --- index.html | 59 ++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/index.html b/index.html index 0ba456a..08af07f 100644 --- a/index.html +++ b/index.html @@ -382,10 +382,9 @@

The cancelIdleCallback() method

The IdleDeadline interface

-

Each IdleDeadline has an associated time - which holds a {{DOMHighResTimeStamp}} representing the absolute time in - milliseconds of the deadline. This MUST be populated when the - IdleDeadline is created.

+

Each IdleDeadline has an associated time getter, an algorithm that + returning a {{DOMHighResTimeStamp}} representing the absolute time in + milliseconds of the deadline, initially set to return zero.

When the timeRemaining() method is invoked on an IdleDeadline object it MUST return the remaining duration before the deadline expires as a {{DOMHighResTimeStamp}}, which SHOULD be @@ -395,12 +394,10 @@

The IdleDeadline interface

  1. Let now be a {{DOMHighResTimeStamp}} representing current high resolution time in milliseconds.
  2. -
  3. Let deadline be the time associated with the - IdleDeadline object.
  4. +
  5. Let deadline be the result of calling the time getter associated with + the IdleDeadline object.
  6. Let timeRemaining be deadline - now.
  7. -
  8. If the user agent now has a time-critical task pending, - set timeRemaining to 0.
  9. If timeRemaining is negative, set it to 0.
  10. Return timeRemaining.
@@ -418,22 +415,23 @@

The IdleDeadline interface

Processing

Start an idle period algorithm

-

The start an idle period algorithm, which is called - by the event loop processing model when it determines that - the event loop is otherwise idle:

+

To start an idle period given {{Window}} window and + getDeadline, an algorithm that returns a {{DOMHighResTimeStamp}}: [[HR-TIME]] + +

The algorithm is called + by the event loop processing model + when it determines that the event loop is otherwise idle.

+
    -
  1. Let last_deadline be the last idle period deadline - associated with window -
  2. If last_deadline is greater than the current time, - return from this algorithm.
  3. Optionally, if the user agent determines the idle period should be delayed, return from this algorithm. -

    This is intended to allow user agents to delay the - start of idle periods as needed to optimise the power usage of the - device. For example, if the {{Document}} is [=Document/hidden=] then the user agent can - throttle idle period generation, for example limiting the Document to - one idle period every 10 seconds to optimize for power usage.

    +

    This is intended to allow user agents to delay the + start of idle periods as needed to optimise the power usage of the + device. For example, if the {{Document}} is [=Document/hidden=] then the user agent can + throttle idle period generation, for example limiting the Document to + one idle period every 10 seconds to optimize for power usage.

  4. +
  5. Let now be the current time.
  6. Let deadline be a time in the future until which the browser expects to remain idle. The user agent SHOULD choose @@ -463,11 +461,9 @@

    Start an idle period algorithm

  7. Clear pending_list.
  8. Queue a task on the queue associated with the idle-task task source, which performs the steps defined in the invoke - idle callbacks algorithm with deadline and - window as parameters. + idle callbacks algorithm with window and getDeadline as + parameters.
  9. -
  10. Save deadline as the last idle period deadline - associated with window.

The task source for these tasks is the idle-task task source.

@@ -481,25 +477,26 @@

Start an idle period algorithm

Invoke idle callbacks algorithm

-

The invoke idle callbacks algorithm:

+

To invoke idle callbacks algorithm given {{Window}} window and + getDeadline, an algorithm returning a {{DOMHighResTimeStamp}}: [[HR-TIME]].

  1. If the user-agent believes it should end the idle period early due to newly scheduled high-priority work, return from the algorithm.
  2. Let now be the current time.
  3. -
  4. If now is less than deadline and the +
  5. If now is less than the result of calling getDeadline and the window's list of runnable idle callbacks is not empty:
    1. Pop the top callback from window's list of runnable idle callbacks.
    2. Let deadlineArg be a new IdleDeadline. - Set the time associated with deadlineArg to - deadline and set the timeout associated with + Set the time getter associated with deadlineArg to + getDeadline and set the timeout associated with deadlineArg to false.
    3. Call callback with deadlineArg as its argument. If an uncaught runtime script error occurs, then [=report the exception=].
    4. If window's list of runnable idle callbacks is not empty, queue a task which performs the steps in the - invoke idle callbacks algorithm with deadline + invoke idle callbacks algorithm with getDeadline and window as a parameters and return from this algorithm
    @@ -526,8 +523,8 @@

    Invoke idle callback timeout algorithm

    callbacks.
  6. Let now be the current time.
  7. Let deadlineArg be a new IdleDeadline. - Set the time associated with deadlineArg to - now and set the timeout associated with + Set the time getter associated with deadlineArg to + an algorithm returning now and set the timeout associated with deadlineArg to true.
  8. Call callback with deadlineArg as its argument. If an uncaught runtime script error occurs, then [=report the exception=].