This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 24114 - [imports]: add support for async loading
Summary: [imports]: add support for async loading
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: HISTORICAL - Component Model (show other bugs)
Version: unspecified
Hardware: PC All
: P2 normal
Target Milestone: ---
Assignee: Dimitri Glazkov
QA Contact: public-webapps-bugzilla
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 20683
  Show dependency treegraph
 
Reported: 2013-12-16 15:33 UTC by Bryan McQuade
Modified: 2014-02-25 21:46 UTC (History)
6 users (show)

See Also:


Attachments

Description Bryan McQuade 2013-12-16 15:33:35 UTC
Resources imported via <link rel=import> are not parser blocking, but are typically render blocking. Render blocking but not parser blocking is the right default behavior, as the primary use case for <link rel=import> is to load content (e.g. custom elements) needed to render that document.

However, a web developer may wish to load an import without blocking rendering. Use cases:
* developer wishes to prefetch a custom element that is not needed to render the initial view, but which will be needed once the user interacts with the web app. developer would like the resource to be loaded and processed once it is available, but does not want rendering of the page to block on the load of that component.
* developer uses a web component that can be sufficiently styled before being upgraded using :unresolved, and thus it is not necessary to block rendering on that component. This only works well for components whose size is known before their custom element has finished loading; else a reflow happens when the component loads and the element changes size.

In these cases, it is preferable that the user of the page not have to wait for the import to finish downloading before they are able to see the other content in the web app display on the screen. However, it is desirable that once the import finishes downloading, that import should be processed and loaded into the document (i.e. this isn't just a prefetch of content into the browser cache), so it is fully loaded and available by the time the web app needs it (thus it's also important that these elements fire a load event so developers know when they are available for use).

Thus, we propose that, like <script async>, we add support for <link rel=import async> to address this use case. At a high level, developers should think of these similarly: "I want to load this script/import but I don't want its load to block the rest of the content on the page from rendering."

There is a key difference between <script async> and <link async>: <script async> indicates that the script should not block the parser. <link rel=import> is already spec'd to not block the parser by default, async or not. However, since imports are intended to block rendering by default, <link async rel=import> indicates that the browser should not block rendering on the load of the imported resource.

I am not aware of render-blocking behavior being spec'd as part of HTML5, and this is probably for good reason: it is up to each user agent (browser) to decide when and what to paint during the course of a web page load. However, in practice, all browsers I'm aware of block rendering on the load of pending stylesheets, and similarly, will block rendering on the load of pending imports. Thus, <link async> is an indicator to the user agent that the load of the imported resource should not block rendering.

In a conversation with dglazkov and esprehn, we proposed that <link async> apply not only to imports, but also to stylesheets. The spec'd behavior should be the same in each case: an import or stylesheet with an async attribute should not block rendering of the page.

Whether to spec this as "should not" or "must not" block rendering is unclear: at first glance, "should not" seems appropriate. However, if spec'd as "should not" and one UA decides not to implement this behavior (they allow async imports to block rendering) then developers will likely abandon this technique and resort to JavaScript workaround that don't work particularly well (i.e. loading the import after a requestAnimationFrame callback, which has various drawbacks). Thus, in order to provide a way to load stylesheets and imports without blocking render that is guaranteed to work across browser vendors, my inclination would be to spec this behavior as "must not block rendering while being loaded".
Comment 1 Jake Archibald 2014-01-29 17:21:16 UTC
I disagree that "Render blocking … is the right default behavior".

Imitating <script> is a poor choice, we're still fighting the render-blocking behaviour <script> provides by default. And <script> makes async really difficult (no way to specify dependencies), just look at Google Analytics https://developers.google.com/analytics/devguides/collection/analyticsjs/.

Instead, we should follow the default behaviour of <img>.

An <img> doesn't block parsing or rendering, the image appears when it is loaded. The developer can reserve an area for the image to change the reflowing behaviour.

This could work for web components. Make :unresolved components display:none by default, then they appear as the import loads & it provides a different value for "display".

The developer can change what :unresolved looks like on a component-by-component basis. This could be reserving space, or even rendering the content within in a way that makes the import an enhancement.

If that absolutely must, they can display:none the <body> and show it once all components are ready. This is a hoop to jump through, but you should have to jump through a hoop to make something totally render-blocking.
Comment 2 Morrita Hajime 2014-02-25 21:46:09 UTC
Introduced @async. 
https://github.com/w3c/webcomponents/commit/61e59e3f8f9ad63c91f814b168df5c4f575cb310

This is just a shorthand to createElement()-appendChild() pattern.