Skip to content

Commit

Permalink
Specify image lazy loading in terms of IntersectionObserver
Browse files Browse the repository at this point in the history
Fixes #5236.

Co-authored-by: Dominic Farolino <[email protected]>
  • Loading branch information
zcorpan and domfarolino authored May 19, 2020
1 parent 319a279 commit 351d56a
Showing 1 changed file with 141 additions and 29 deletions.
170 changes: 141 additions & 29 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -3643,6 +3643,12 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute

<ul class="brief">
<li><dfn data-x-href="https://w3c.github.io/IntersectionObserver/#run-the-update-intersection-observations-steps">run the update intersection observations steps</dfn></li>
<li><dfn data-x-href="https://w3c.github.io/IntersectionObserver/#intersectionobserver"><code>IntersectionObserver</code></dfn></li>
<li><dfn data-x-href="https://w3c.github.io/IntersectionObserver/#dictdef-intersectionobserverinit"><code>IntersectionObserverInit</code></dfn></li>
<li><dfn data-x-href="https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-observe" data-x="dom-IntersectionObserver-observe"><code>observe</code></dfn></li>
<li><dfn data-x-href="https://w3c.github.io/IntersectionObserver/#dom-intersectionobserver-unobserve" data-x="dom-IntersectionObserver-unobserve"><code>unobserve</code></dfn></li>
<li><dfn data-x-href="https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-isintersecting" data-x="dom-IntersectionObserverEntry-isIntersecting"><code>isIntersecting</code></dfn></li>
<li><dfn data-x-href="https://w3c.github.io/IntersectionObserver/#dom-intersectionobserverentry-target" data-x="dom-IntersectionObserverEntry-target"><code>target</code></dfn></li>
</ul>
</dd>

Expand Down Expand Up @@ -6794,6 +6800,132 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
data-x="invalid value default">invalid value default</i> are both the <span
data-x="attr-loading-eager-state">Eager</span> state.</p>

<hr>

<p>The <dfn>will lazy load element steps</dfn>, given an element <var>element</var>,
are as follows:</p>

<ol>
<li>
<p>If <span data-x="concept-n-noscript">scripting is disabled</span> for <var>element</var>,
then return false.</p>

<p class="note">This is an anti-tracking measure, because if a user agent supported lazy loading
when scripting is disabled, it would still be possible for a site to track a user's approximate
scroll position throughout a session, by strategically placing images in a page's markup such
that a server can track how many images are requested and when.</p>
</li>

<li><p>If <var>element</var>'s <span>lazy loading attribute</span> is in the <span
data-x="attr-loading-lazy-state">Lazy</span> state, then return true.</p></li>

<li><p>Return false.</p></li>
</ol>

<p>Each <code>img</code> element has an associated <dfn>ready to be lazy loaded</dfn> boolean,
initially false.</p>

<p class="note">For <code>img</code> elements that <span data-x="will lazy load element
steps">will lazy load</span>, this can be set to true in the <span>lazy load intersection
observer</span>'s callback, which causes the image to load by continuing the <span>update the
image data</span> steps.</p>

<p>Each <code>Document</code> has a <dfn>lazy load intersection observer</dfn>, initially set to
null but can be set to an <code>IntersectionObserver</code> instance.</p>

<p>To <dfn>start intersection-observing a lazy loading element</dfn> <var>element</var>, run these
steps:</p>

<ol>
<li><p>Let <var>doc</var> be <var>element</var>'s <span>node document</span>.</p></li>

<li>
<p>If <var>doc</var>'s <span>lazy load intersection observer</span> is null, set it to a new
<code>IntersectionObserver</code> instance, initialized as follows:</p>

<p class="XXX">The intention is to use the original value of the
<code>IntersectionObserver</code> constructor. However, we're forced to use the
JavaScript-exposed constructor in this specification, until <cite>Intersection Observer</cite>
exposes low-level hooks for use in specifications. See bug <a
href="https://github.com/w3c/IntersectionObserver/issues/427">w3c/IntersectionObserver#427</a>
which tracks this. <ref spec="INTERSECTIONOBSERVER"></p>

<ul>
<li>
<p>The <var>callback</var> is these steps, with arguments <var>entries</var> and
<var>observer</var>:</p>

<ol>
<li>
<p>For each <var>entry</var> in <var>entries</var> <span class="XXX">using a method of
iteration which does not trigger developer-modifiable array accessors or
iteration hooks</span>:

<ol>
<li>
<p>If <var>entry</var>.<code
data-x="dom-IntersectionObserverEntry-isIntersecting">isIntersecting</code> is true, set
<var>entry</var>.<code data-x="dom-IntersectionObserverEntry-target">target</code>'s
<span>ready to be lazy loaded</span> boolean to true.</p>

<p class="XXX">The intention is to use the original value of the
<code data-x="dom-IntersectionObserverEntry-isIntersecting">isIntersecting</code> and
<code data-x="dom-IntersectionObserverEntry-target">target</code> getters. See <a
href="https://github.com/w3c/IntersectionObserver/issues/427">w3c/IntersectionObserver#427</a>.
<ref spec="INTERSECTIONOBSERVER"></p>
</li>
</ol>
</li>
</ol>
</li>

<li>
<p>The <var>options</var> is an <code>IntersectionObserverInit</code> dictionary with the
following dictionary members: «[ "<code data-x="">rootMargin</code>" → an
<span>implementation-defined</span> value ]»</p>

<p class="XXX">See <a
href="https://github.com/whatwg/html/issues/5408">issue #5408</a>.</p>

<p class="note">This allows for fetching the image during scrolling, when it does not yet —
but is about to — intersect the viewport.</p>
</li>
</ul>
</li>

<li>
<p>Call <var>doc</var>'s <span>lazy load intersection observer</span>'s <code
data-x="dom-IntersectionObserver-observe">observe</code> method with <var>element</var> as the
argument.</p>

<p class="XXX">The intention is to use the original value of the <code
data-x="dom-IntersectionObserver-observe">observe</code> method. See <a
href="https://github.com/w3c/IntersectionObserver/issues/427">w3c/IntersectionObserver#427</a>.
<ref spec="INTERSECTIONOBSERVER"></p>
</li>
</ol>

<p>To <dfn>stop intersection-observing a lazy loading element</dfn> <var>element</var>, run these
steps:</p>

<ol>
<li><p>Let <var>doc</var> be <var>element</var>'s <span>node document</span>.</p></li>

<li><p>Assert: <var>doc</var>'s <span>lazy load intersection observer</span> is not
null.</p></li>

<li>
<p>Call <var>doc</var>'s <span>lazy load intersection observer</span> <code
data-x="dom-IntersectionObserver-unobserve">unobserve</code> method with <var>element</var> as
the argument.</p>

<p class="XXX">The intention is to use the original value of the <code
data-x="dom-IntersectionObserver-unobserve">unobserve</code> method. See <a
href="https://github.com/w3c/IntersectionObserver/issues/427">w3c/IntersectionObserver#427</a>.
<ref spec="INTERSECTIONOBSERVER"></p>
</li>
</ol>


<h3 split-filename="common-dom-interfaces">Common DOM interfaces</h3>

Expand Down Expand Up @@ -27330,33 +27462,6 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code

<h6>Updating the image data</h6>

<p>The <dfn>will lazy load image steps</dfn>, given an <code>img</code> element <var>img</var>,
are as follows:</p>

<ol>
<li>
<p>If <span data-x="concept-n-noscript">scripting is disabled</span> for <var>img</var>, return
false.</p>

<p class="note">This is an anti-tracking measure, because if a user agent supported lazy loading
when scripting is disabled, it would still be possible for a site to track a user's approximate
scroll position throughout a session, by strategically placing images in a page's markup such
that a server can track how many images are requested and when.</p>
</li>

<li>
<p>If <var>img</var>'s <span>lazy loading attribute</span> is in the <span
data-x="attr-loading-lazy-state">Lazy</span> state, <var>img</var> does not <span>intersect the
viewport</span>, and <var>img</var> is not about to <span>intersect the viewport</span>, then
return true.</p>

<p class="note">This allows for fetching the image during scrolling, when it does not, but is
about to intersect the viewport.</p>
</li>

<li><p>Return false.</p></li>
</ol>

<p class="note">This algorithm cannot be called from steps running <span>in parallel</span>. If
a user agent needs to call this algorithm from steps running <span>in parallel</span>, it needs to
<span data-x="queue a task">queue</span> a task to do so.</p>
Expand Down Expand Up @@ -27578,15 +27683,22 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code
false otherwise.</p></li>

<li>
<p>If the <span>will lazy load image steps</span> given the <code>img</code> return true,
<p>If the <span>will lazy load element steps</span> given the <code>img</code> return true,
then:</p>

<ol>
<li><p><span>Start intersection-observing a lazy loading element</span> for the
<code>img</code> element.</p></li>

<li><p>Continue running this algorithm <span>in parallel</span>.</p></li>

<li><p>Wait until the <span>will lazy load image steps</span> no longer return true, given the
<li><p>Wait until the <code>img</code>'s <span>ready to be lazy loaded</span> flag is
true, or until the <span>will lazy load element steps</span> no longer return true, given the
<code>img</code>.</p></li>

<li><p><span>Stop intersection-observing a lazy loading element</span> for the <code>img</code>
element.</p></li>

<li><p><span>Queue an element task</span> on the <span>DOM manipulation task source</span>
given the <code>img</code> element to continue running the rest of this algorithm.</p></li>
</ol>
Expand Down

0 comments on commit 351d56a

Please sign in to comment.