Skip to content

Commit

Permalink
Rely on HTML spec for deadline computation
Browse files Browse the repository at this point in the history
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
  • Loading branch information
noamr committed Oct 7, 2021
1 parent f1be6e9 commit e63caef
Showing 1 changed file with 28 additions and 31 deletions.
59 changes: 28 additions & 31 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,9 @@ <h2>The <dfn>cancelIdleCallback()</dfn> method</h2>
</section>
<section data-dfn-for="IdleDeadline">
<h2>The <dfn>IdleDeadline</dfn> interface</h2>
<p>Each <a>IdleDeadline</a> has an associated <dfn>time</dfn>
which holds a {{DOMHighResTimeStamp}} representing the absolute time in
milliseconds of the deadline. This MUST be populated when the
<a>IdleDeadline</a> is created.</p>
<p>Each <a>IdleDeadline</a> has an associated <dfn>time getter</dfn>, an algorithm that
returning a {{DOMHighResTimeStamp}} representing the absolute time in
milliseconds of the deadline, initially set to return zero.
<p>When the <dfn>timeRemaining()</dfn> method is invoked on
an <a>IdleDeadline</a> object it MUST return the remaining duration before
the deadline expires as a {{DOMHighResTimeStamp}}, which SHOULD be
Expand All @@ -395,12 +394,10 @@ <h2>The <dfn>IdleDeadline</dfn> interface</h2>
<ol>
<li>Let <var>now</var> be a {{DOMHighResTimeStamp}} representing
<a>current high resolution time</a> in milliseconds.</li>
<li>Let <var>deadline</var> be the <a>time</a> associated with the
<a>IdleDeadline</a> object.</li>
<li>Let <var>deadline</var> be the result of calling the <a>time getter</a> associated with
the <a>IdleDeadline</a> object.</li>
<li>Let <var>timeRemaining</var> be <var>deadline</var> -
<var>now</var>.</li>
<li>If the user agent now has a time-critical task pending,
set <var>timeRemaining</var> to 0.</li>
<li>If <var>timeRemaining</var> is negative, set it to 0.</li>
<li>Return <var>timeRemaining</var>.</li>
</ol>
Expand All @@ -418,22 +415,23 @@ <h2>The <dfn>IdleDeadline</dfn> interface</h2>
<h2>Processing</h2>
<section>
<h2>Start an idle period algorithm</h2>
<p>The <dfn>start an idle period algorithm</dfn>, which is called
by the <a data-cite="html#event-loop-processing-model">event loop processing model</a> when it determines that
the <a>event loop</a> is otherwise idle:</p>
<p>To <dfn export>start an idle period</dfn> given {{Window}} <var>window</var> and
<var>getDeadline</var>, an algorithm that returns a {{DOMHighResTimeStamp}}: [[HR-TIME]]

<p class="note">The algorithm is called
by the <a data-cite="html#event-loop-processing-model">event loop processing model</a>
when it determines that the <a>event loop</a> is otherwise idle.</p>

<ol>
<li>Let <var>last_deadline</var> be the <a>last idle period deadline</a>
associated with <var>window</var>
<li>If <var>last_deadline</var> is greater than the current time,
return from this algorithm.
<li>Optionally, if the user agent determines the idle period should
be delayed, return from this algorithm.
<p class='note' data-cite="page-visibility-2">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.</p>
<p class='note' data-cite="page-visibility-2">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.</p>
</li>

<li>Let <var>now</var> be the current time.</li>
<li>Let <var>deadline</var> be a time in the future until which the
browser expects to remain idle. The user agent SHOULD choose
Expand Down Expand Up @@ -463,11 +461,9 @@ <h2>Start an idle period algorithm</h2>
<li>Clear <var>pending_list</var>.</li>
<li><a>Queue a task</a> on the queue associated with the idle-task
<a>task source</a>, which performs the steps defined in the <a>invoke
idle callbacks algorithm</a> with <var>deadline</var> and
<var>window</var> as parameters.
idle callbacks algorithm</a> with <var>window</var> and <var>getDeadline</var> as
parameters.
</li>
<li>Save <var>deadline</var> as the <a>last idle period deadline</a>
associated with <var>window</var>.</li>
</ol>
<p>The <a>task source</a> for these <a>tasks</a> is the <dfn>idle-task
task source</dfn>.</p>
Expand All @@ -481,25 +477,26 @@ <h2>Start an idle period algorithm</h2>
</section>
<section>
<h2>Invoke idle callbacks algorithm</h2>
<p>The <dfn>invoke idle callbacks algorithm</dfn>:</p>
<p>To <dfn>invoke idle callbacks algorithm</dfn> given {{Window}} <var>window</var> and
<var>getDeadline</var>, an algorithm returning a {{DOMHighResTimeStamp}}: [[HR-TIME]].</p>
<ol>
<li>If the user-agent believes it should end the idle period early due
to newly scheduled high-priority work, return from the algorithm.
<li>Let <var>now</var> be the current time.</li>
<li>If <var>now</var> is less than <var>deadline</var> and the
<li>If <var>now</var> is less than the result of calling <var>getDeadline</var> and the
<var>window</var>'s <a>list of runnable idle callbacks</a> is not empty:
<ol>
<li>Pop the top <var>callback</var> from <var>window</var>'s
<a>list of runnable idle callbacks</a>.</li>
<li>Let <var>deadlineArg</var> be a new <a>IdleDeadline</a>.
Set the <a>time</a> associated with <var>deadlineArg</var> to
<var>deadline</var> and set the <a>timeout</a> associated with
Set the <a>time getter</a> associated with <var>deadlineArg</var> to
<var>getDeadline</var> and set the <a>timeout</a> associated with
<var>deadlineArg</var> to <code>false</code>.</li>
<li>Call <var>callback</var> with <var>deadlineArg</var> as its
argument. If an uncaught runtime script error occurs, then [=report the exception=].</li>
<li>If <var>window</var>'s <a>list of runnable idle callbacks</a>
is not empty, <a>queue a task</a> which performs the steps in the
<a>invoke idle callbacks algorithm</a> with <var>deadline</var>
<a>invoke idle callbacks algorithm</a> with <var>getDeadline</var>
and <var>window</var> as a parameters and return from this
algorithm</li>
</ol>
Expand All @@ -526,8 +523,8 @@ <h2>Invoke idle callback timeout algorithm</h2>
callbacks</a>.</var></li>
<li>Let <var>now</var> be the current time.</li>
<li>Let <var>deadlineArg</var> be a new <a>IdleDeadline</a>.
Set the <a>time</a> associated with <var>deadlineArg</var> to
<var>now</var> and set the <a>timeout</a> associated with
Set the <a>time getter</a> associated with <var>deadlineArg</var> to
an algorithm returning <var>now</var> and set the <a>timeout</a> associated with
<var>deadlineArg</var> to <code>true</code>.</li>
<li>Call <var>callback</var> with <var>deadlineArg</var> as its
argument. If an uncaught runtime script error occurs, then [=report the exception=].</li>
Expand Down

0 comments on commit e63caef

Please sign in to comment.