Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved. W3C liability, trademark and document use rules apply.
This specification defines a means for site developers to programmatically give the User Agent hints on the download priority of a resource. This will allow User Agents to more efficiently manage the order in which resources are downloaded.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This is an editor's draft and may change without any notices.
Please send comments to public-web-perf@w3.org (archived) with [ResourcePriorities] at the start of the subject line.
This document is produced by the Web Performance Working Group.
lazyload
attributeimg
elementaudio
elementvideo
elementscript
elementlink
elementembed
elementiframe
elementobject
elementsvg feImage
filter primitivesvg image
elementsvg use
elementsvg script
elementsvg tref
elementThis section is non-normative.
The Resource Priorities specification defines a means for site developers to programmatically give
the User Agent hints on the download priority of a resource. Without knowing the download priority of
a resource, the User Agent will typically download resources in document order. However, the download
order may not be best optimized for improving both the perceived and real page load performance.
By specifying lower priority resources using the lazyload
attribute,
the User Agent is able to better optimize download order when the User Agent is in a resource constrained
environment and sooner execute scripts triggered by the load event of the Document.
Today, most developers trigger script execution based on the load event of the Document. However,
the load event can be delayed by resources that are not necessary for page load visuals and do not interact
with script. For example, a site may have images well below the fold that are delaying
how long it takes the load event of the document to fire, delaying scripts from executing. Specifying
the lazyload
attribute on an element downloading a resource allows the User Agent to not block
the load event of the Document on those resources. By specifying the lazyload
attribute on
resources that have no interaction with script or are not necessary for above the fold visuals,
scripts can execute sooner, improving real world page load performance.
Site developers can improve the perception of page load performance by optimizing the download of resources when there is network resource contention such that downloads for resources not required to create the above the fold visuals are prioritized lower. However, determining which resources are required to create the above the fold visuals for a web page is something the User Agent cannot easily determine on its own. Instead, the site developer is in the best position to let the User Agent know the relative priorities of resources on their web application.
The following example shows a theoretical web page that doesn't specify the download priority of resources. In this example, the site developer will use Stylesheets from Styles.css and script within Visuals.js to re-layout the page such that Logo.png, Header.png, and MainContent.mp4 will be shown above the fold, whereas AdditionalImages1.png and AdditionalImages2.png will be shown below the fold. Animations.css is used to display an animation when a user clicks on an image and Analytics.js is used to collect analytics information, both not executed during the page load.
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" src="Styles.css" /> <link rel="stylesheet" type="text/css" src="Animations.css" /> </head> <body> <img id="Logo" src=".../images/Logo.png"/> <img id="Header" src=".../images/Header.png"/> <img id="AdditionalImages1" src=".../images/AdditionalImages1.png"/> <img id="AdditionalImages2" src=".../images/AdditionalImages2.png"/> <video id="MainContent"><source src=".../videos/MainContent.mp4"></video> <script src="Visuals.js" ></script> <script src="Analytics.js" ></script> </body> </html>
As the example page has been specified, a User Agent may download resources in the following order: root document, CSS in document order, JavaScript in document order, and everything else in document order. In this case, AdditionalImages1.png and AddtionalImages.png will be downloaded before MainContent.mp4, even though they will not be displayed above the fold when the page loads. Additionally, Animations.css and Analytics.js will be downloaded prior to the visual aspect of the page, even though they won't be used in the page load sequence.
Using the lazyload
attribute on a resource will signal to the User Agent that
in cases of network resource contention, it may lower the download priority of that resource.
The following example shows the same theoretical web page but with the lazyload
attribute set for
resources whose download priority can be reduced, as they do not impact the visual appearance of the page
above the fold.
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" src="Styles.css" /> <link rel="stylesheet" type="text/css" src="Animations.css" lazyload /> </head> <body> <img id="Logo" src=".../images/Logo.png"/> <img id="Header" src=".../images/Header.png"/> <img id="AdditionalImages1" src=".../images/AdditionalImages1.png" lazyload /> <img id="AdditionalImages2" src=".../images/AdditionalImages2.png" lazyload /> <video id="MainContent"><source src=".../videos/MainContent.mp4"></video> <script src="Visuals.js" ></script> <script src="Analytics.js" lazyload ></script > </body> </html>
In this example page, using the lazyload
attribute
User Agent may instead download resources in the following order: root document,
Styles.css, Visuals.js, Logo.png, Header.png, MainContent.mp4, Animations.css, Analytics.js, AdditionalImages1.png
and AdditionalImages2.png.
Some applications require a large number of resources that may not be required immediately. For example,
a Canvas game may have multiple game levels with different assets required for each level.
Instead of slowing down the initial application loading experience by loading all assets during the
page load, developers can use the lazyload
attribute on resources that they do not need immediately.
These resources won't block script execution, as the load event of the Document will not be delayed, and in cases
of network resource contention, the User Agent will optimize downloading the higher priority resources.
The following example shows a theoretical game application that is using lazyload
to differentiate
between assets that are required more immediately and assets that are not required immediately.
<!DOCTYPE html> <html> <head> </head> <body onload='init()'> <canvas id='GameCanvas'></canvas> <img class='Backgrounds' id='BackgroundLevel1' src='Background1.png' /> <img class='Backgrounds' id='BackgroundLevel2' src='Background2.png' lazyload /> <script> var assets = []; var NUM_ASSETS_LEVEL1 = 100; var NUM_ASSETS_LEVEL2 = 100; var NUM_ASSETS_GENERAL = 100; var URL_LEVEL1_ASSETS = "assets\\level1\\"; var URL_LEVEL2_ASSETS = "assets\\level2\\"; var URL_GENERAL_ASSETS = "assets\\general\\"; function init() { // Load game assets loadGameAssets(); // Play game } function loadGameAssets() { var i, j, k; // Load assets required for Level 1 for (i = 0; i < NUM_ASSETS_LEVEL1; i++) { assets[i] = new Image(); assets[i].src = URL_LEVEL1_ASSETS + i + ".png"; } // Lazyload assets required for Level 2 for (j = 0; j < NUM_ASSETS_LEVEL2; j++) { assets[i + j] = new Image(); assets[i + j].setAttribute('lazyload'); assets[i + j].src = URL_LEVEL2_ASSETS + j + ".png"; } // Load additional assets required for all levels for (k = 0; k < NUM_ASSETS_GENERAL; k++) { assets[i + j + k] = new Image(); assets[i + j + k].src = URL_GENERAL_ASSETS + k + ".png"; } } </script> </body> </html>
In the previous example, downloading the Background2.png specified in markup does not block the load event of the page
as it has been marked with lazyload
. Similarly, for the dynamically loaded resources,
if there had been a network resource contention, the User Agent would have prioritized the downloads for level 1
and general assets over level 2 assets.
All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC 2119. For readability, these words do not appear in all uppercase letters in this specification.
Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.
Some conformance requirements are phrased as requirements on attributes, methods or objects. Such requirements are to be interpreted as requirements on user agents.
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)
The IDL fragments in this specification must be interpreted as required for conforming IDL fragments, as described in the Web IDL specification. [Web IDL]
The construction "a Foo
object", where Foo
is actually an interface, is sometimes used instead of
the more accurate "an object implementing the interface Foo
".
Network resource contention is defined as when the User Agent determines there is a conflict over access to network resources. An example of network resource contention is when a User Agent is unable to start downloading a resource because the User Agent has exhausted all available TCP connections.
This section is non-normative.
This specification defines a means for site developers to programmatically give the User Agent hints on the download priority of a resource. This will allow User Agents to more efficiently manage the order in which resources are downloaded when there is network resource contention or when the resource is not visible to the user, and allow the load event of the Document to fire sooner as it will not be blocked for lower priority resources.
lazyload
attribute
The lazyload
attribute is a boolean and IDL attribute
that indicates the priority order in which the User Agent should download the resource associated with
the element in cases of network resource contention.
If the User Agent determines that there is network resource contention,
the User Agent SHOULD delay downloading resources associated with elements that have the lazyload
boolean attribute specified on the
element until all other resources associated with elements that do not have the lazyload
boolean attribute specified on the
element have started downloading.
An example of network resource contention can be if there is a connection contention where the User
Agent is using all available connections. A User Agent may give available TCP connections,
or give a more optimized TCP connection if there is a choice between available connections,
to resources that don’t have the lazyload
attribute.
The lazyload
IDL attribute MUST
reflect the
lazyload
boolean attribute value.
The lazyload
boolean and IDL attributes are supported
on the following HTML elements
and SVG elements
capable of fetching resources:
img
,
audio
,
video
,
script
,
link
,
embed
,
iframe
,
object
,
svg
feImage
,
svg
image
,
svg
use
,
svg
script
,
and svg
tref
.
img
elementlazyload
partial interface HTMLImageElement { attribute boolean lazyload; };
The img
element supports the lazyload
attribute.
audio
elementlazyload
partial interface HTMLAudioElement { attribute boolean lazyload; };
The audio
element supports the lazyload
attribute.
video
elementlazyload
partial interface HTMLVideoElement { attribute boolean lazyload; };
The video
element supports the lazyload
attribute.
script
elementlazyload
partial interface HTMLScriptElement { attribute boolean lazyload; };
The script
element supports the lazyload
boolean attribute, along with the defer
and async
boolean attributes, to indicate the order in which the user agent will download and execute the script.
There are a few possible modes that can be selected using these attributes:
If the lazyload
and async
attributes
are present, if there is network resource contention the User Agent SHOULD delay downloading the script until after all other
elements
without the lazyload
attribute that will be
fetching a resource
have started downloading, and then the script MUST be executed asynchronously, as soon as it is available.
If the lazyload
and defer
attributes
are present, the defer
attribute behavior takes precedence and the lazyload
attribute will have no effect.
If only the lazyload
attribute is present,
the User Agent MUST run the same steps as if both the lazyload
and async
attributes
were present.
If the async
IDL attribute of the script
element is set to false
, the lazyload
attribute will have no effect.
link
elementlazyload
partial interface HTMLLinkElement { attribute boolean lazyload; };
The link
element supports the lazyload
attributes.
The User Agent MUST NOT block rendering on stylesheets that have the
lazyload
boolean attribute specified on the associated link
element or
the lazyload
IDL attribute set to true on the associated link
element.
The User Agent parser MUST NOT block launching new script contexts on stylesheets that have the
lazyload
boolean attribute specified on the associated link
element or
the lazyload
IDL attribute set to true on the associated link
element.
embed
elementlazyload
partial interface HTMLEmbedElement { attribute boolean lazyload; };
The embed
element supports the lazyload
attribute.
iframe
elementlazyload
partial interface HTMLIFrameElement { attribute boolean lazyload; };
The iframe
element supports the lazyload
attribute.
object
elementlazyload
partial interface HTMLObjectElement { attribute boolean lazyload; };
The object
element supports the lazyload
attribute.
svg
feImage
filter primitivelazyload
partial interface SVGFEImageElement { attribute boolean lazyload; };
The svg feImage
primitive supports the lazyload
attribute.
If the externalResourcesRequired
attribute is set to true, the
lazyload
attribute will have no effect.
svg
image
elementlazyload
partial interface SVGImageElement { attribute boolean lazyload; };
The svg image
element supports the lazyload
attribute.
svg
use
elementlazyload
partial interface SVGUseElement { attribute boolean lazyload; };
The svg use
element supports the lazyload
attribute.
svg
script
elementlazyload
partial interface SVGScriptElement { attribute boolean lazyload; };
The svg script
element supports the lazyload
attribute.
svg
tref
elementlazyload
partial interface SVGTRefElement { attribute boolean lazyload; };
The svg tref
element supports the lazyload
attribute.
load
event
The load
event of the Document MUST NOT be blocked by any element
with the lazyload
content attribute specified or the lazyload
IDL attribute set to true.
The load
event of an element with
the lazyload
attribute MUST continue to be blocked until the resource is loaded.
The lazyload
attribute MUST not change when the DOMContentLoaded
event is fired or the behavior of the
loading
, interactive
, and complete
states of the Document's
readyState
IDL attribute.
lazyloaded
event
Immediately after all elements with the lazyload
content attribute
specified or lazyload
IDL attribute set to true have their resources downloaded, the User Agent MUST queue a task to fire a simple
event lazyloaded
at the Document. If there are no elements with the
lazyload
content attribute specified or with the lazyload
IDL attribute set to true,
the User Agent MUST queue a task to fire the lazyloaded
event at the Document immediately after the load
event of the Document has been fired.
We would like to sincerely thank Bruno Racineux, Jake Archibald, Jason Weber, Josh Tumath, Tony Ross, Travis Leithead, Yoav Weiss, Marcos Caceres, Brian Birtles, Ivan Kotenkov, Erik Dahlstrom, Boris Zbarsky, William Chan, and Shwetank Dixit to acknowledge their contributions to this work.