Re: [HTML Imports]: Sync, async, -ish?

Second question: should *rendering* of page content block on the load of
<link rel=import>

Steve Souders wrote another nice post about this topic:
http://www.stevesouders.com/blog/2013/11/26/performance-and-custom-elements/which
I recommend reading (read the comments too).

We should start by looking to how the web platform behaves today. All
browsers I am aware of block rendering on the load of pending stylesheets.
Note that blocking rendering (blocking of render tree construction and
painting content to the screen) is different from blocking parsing.
Browsers do not block HTML parsing (DOM construction) on stylesheets. Nor
should they block DOM construction on loading of <link rel=import>s.

The reason to block rendering while a custom element's load is pending is
to prevent a flash of unstyled content/reflow of content on the page. At a
high level:
* a FOUC is caused when the "styling" (e.g. color/font/border/background
color/etc) of the element changes as a result of applying styles
* a reflow is caused when the position (e.g. x/y/width/height) of the
element changes as a result of applying styles

If a custom element does not change its positioning as a result of being
styled, i.e. its x/y/width/height coordinates do not change as a result of
the custom element's styles being applied (i.e. as a result of being
upgraded), then it seems reasonable to not block rendering of the rest of
the page on the load of that element. Additionally, one can use :unresolved
to style such an element while it is being loaded.

However, if the positioning of the custom element changes as a result of
its being upgraded, i.e. its x/y/width/height changes, then the styling of
that element may cause a reflow, causing other content on the screen that
may have already rendered to move around. Imagine two siblings in the DOM
that each have display:inline-block. If the first is a custom element, and
its width changes when it upgrades, it'll cause the next sibling and any
subsequent siblings to shift right and possibly to wrap to the next line if
they exceed the width of the parent. As Steve notes in a comment on his
post, :unresolved can't be used to prevent other elements on the screen
from moving around in this case. This results in a bad user experience
(we've all experienced the annoying behavior of content moving as we are
reading it, due to a reflow) and the web platform should try to prevent
this.

So how do we strike a balance between fast rendering and avoiding
reflow/content moving around on the screen? In the case of custom elements
there are a few things that browsers can do:

1. if there are no custom elements in the DOM, then even if a load of a
custom element import is pending, then there is no reason to block
rendering of the rest of the page, since the custom element's load can't
impact the styling of content in the DOM.
2. if there are custom elements in the DOM and a custom element import's
load is pending, *and* it can be determined by the rendering engine that
the load/upgrade of that element will not cause its *position* to change
(e.g. that element has a "style="width:x;height:y;" attribute, or a
style="display:none", etc - we'll have to overlook !important styles for
this...) then we should not block rendering of the rest of the page, since
the content other than the custom element will not change position as a
result of the custom element loading.

However, if there are custom elements in the DOM whose position isn't
specified in an inline style, and a custom element import load is pending,
then rendering (not parsing!) should block until that custom element has
finished loading, to prevent a FOUC/reflow.

If we take this approach, then developers have two ways to prevent the load
of custom elements from blocking rendering:
1. don't add custom elements to the DOM before the custom element's
imported content has finished loading
2. explicitly specify the positioning of the custom element in an inline
style to tell the rendering engine that its position is fixed and will not
change as a result of being upgraded

So, I propose that, similar to pending stylesheets, the load of custom
elements should block rendering. With custom elements, however, we can be a
bit smarter than with stylesheets: rendering should block only in cases
where the upgrade of a custom element in the DOM might cause a reflow,
moving other page content on the screen.

Received on Tuesday, 3 December 2013 19:23:04 UTC