[whatwg] defer on style, depends

Garrett Smith dhtmlkitchen at gmail.com
Sun Feb 15 09:46:22 PST 2009

On Fri, Feb 13, 2009 at 12:34 AM, Ian Hickson <ian at hixie.ch> wrote:
> On Mon, 9 Feb 2009, Boris Zbarsky wrote:
>> Ian Hickson wrote:
>> > I'm not convinced either of these are really great solutions. I think it'd
>> > be better just to have the script itself only block when it hits
>> > CSS-dependent APIs (though I recognise that that is a much harder problem in
>> > most rendering engines today).
>> I'm not sure how you envision this working.  The run-to-completion
>> semantics mean that while the script is working on the API call to
>> return (which means that network events are being processed, etc), the
>> following invariants need to be maintained (list very much not
>> exhaustive):
>> 1)  No setTimeout timers fire.
>> 2)  No XMLHttpRequest state changes happen.
>> 3)  No image load events fire.
>> 4)  No stylesheet load events fire (for UAs that implement such an
>>     event on their <link> elements, as Gecko would like to do).
>> 5)  No user interaction with the page or other pages that can reach the
>>     given page is allowed.
>> #5 makes it unlikely that a UA would want to go this route at all.  #4
>> means that this approach would be incompatible with reasonable style
>> load events... #1, #2, #3 all mean that networking needs to
>> differentiate between the set of stylesheets we're waiting on and
>> everything else.
> Yeah, fair enough.
> By the way, the spec doesn't yet require the blocking behavior. I couldn't
> work out how to do it. Could you elaborate on when exactly in the process
> the style sheet is waited on? Does it happen for all scripts? For example,
> if a script inserts a style sheet and then a script, does that script wait
> for the style sheet to load?
> On Mon, 9 Feb 2009, Garrett Smith wrote:
>> If I put the script at the bottom of the page, and a linked stylesheet
>> in the head, the script waits for the stylesheet.
>> I want my page to load faster and this feature prevents it.
> Put the script in the <head> before the style sheet and use the "defer"
> attribute so that it runs the script as if it was at the end of the page.
>> > It seems pretty simple to me; if you want the style to be loaded when
>> > the script runs, put the style first. If you don't, put the script
>> > first and defer it (or mark it async). Why should this not be enough?
>> The implementation might delayed the page from rendering when it sees
>> the stylesheet.
> That's unrelated to scripts, though, right?
> If you don't want the script to block page load, then speak to your
> browser vendor. The spec doesn't require that.
>> The script's defer attribute does not work in a majority of
>> implementations. For such browsers, it makes sense to put the script
>> lower on the page for performance reasons, not before the linked
>> stylesheets. Moving the deferred script from the bottom of the page to
>> the head, just before the stylesheet would mean that those scripts would
>> load first. This would prevent the page content from loading until those
>> scripts had loaded. This would hurt performance in the majority of
>> browsers in use today.
> Sure, but then the feature you describe doesn't work in today's browsers
> either, so that seems like a wash.
> On Mon, 9 Feb 2009, Garrett Smith wrote:
>> There are two/three issues.
>> 1) want to load stylesheets without having scripts block
> Put the scripts first.

Then the scripts block. I explained this and showed this in examples.

If the script is deferred, it will wait for the stylesheet.

>> 2) want to load stylesheets later, (infoPanel example)
> Put the styles later.
The script blocks the stylesheet.

>> 3) (2), but want to make sure the stylesheet is loaded before the script runs.
> Put the styles first.
The stylesheet can be placed right before the script which depends on
it, right before closing body tag:


and the result will "work" in Firefox. However, that does not works
consistently in a wide enough range of current browsers. Particularly,
Webkit and Opera will alert('loaded') before getting the stylesheet.

>> Example 1:
>> <head><title></title>
>> <link independent type="text/css"  ...>
>> <script...></script>
>> I want the browser to:
>> 1) load my stylesheet and then immediately begin to load script in parallel.
> Put the script first with a defer or async attribute.

I have already explained why this is going to make the page
functionally inconsistent and hard to maintain across a set of
browsers where some browsers have support for defer and others do not.

The deferred "alert" external script will run first in  browsers that
ignore defer. In browsers that do not ignore defer, (Firefox 3.1 pre)
it will run last, after the stylesheet is loaded. Boris explained that
current Gecko behavior is that any stylesheet load started by parsing
a <style> or <link> tag will increment a counter on the script loader
object for that document.

This also explains why putting deferred scripts first will hurt
performance in both cases.

Putting deferred scripts first is a really bad idea.

>> Example 2
>> <head><title></title>
>> <link defer type="text/css" id="lateBoundCSS" ...>
>> </head>
>> <body>
>> ...
>> <script depends="lateBoundCSS"...></script>
>> </body>
>> I want the browser to:
>> 1) defer my linked stylesheet id="lateBoundCSS" until content is rendered
>> 2) render content
>> 3) upon encountering the deferred script, check the depends
>> 4) upon finding Result(3) is "lateBoundCSS", wait for that resource to
>> finish load before running.
> I don't really think that makes sense. Why would you depend on just one
> style sheet and not the others? What if the others change the styles of
> the content you're dealing with?

The other stylesheets would not include style information for
infoPanel. That would go in infoPanel.css. In the build, infoPanel.css
could combined with other stylesheets that did not need to be loaded
first, such as searchSuggest.css.

That was covered by the infoPanel example that I provided.

> You could do this, however, using a 'load' event listener on the <link>
> (though the spec doesn't yet support that -- I'm trying to reduce the
> amount of stuff I do using progress events until progress events is
> further along REC track), or, more simply, by just waiting for the
> document-wide 'load' event (though that won't wait for just the style
> sheet, it'll wait for everything).

A load event on link would fire when the link is done loading. When
you say "the document-wide load event," I think you mean
window.onload. Waiting for that would offer no performance benefit. It
would hurt performance and user experience. As such, that does not
fulfill the case where a script depends on a stylesheet.

> On Mon, 9 Feb 2009, Boris Zbarsky wrote:
>> Not sure what this example is, or why this is insufficienty served by,
>> say, putting the <link> at the end of the HTML (assuming HTML allowed
>> that, of course).
> The markup doesn't allow it but you can always do it from script.

Ian, you have once again snipped what I wrote, taking things out of
context. Once again, I would like to ask that you please do not do

What I wrote, prior to boris saying "not sure what this example is":

|  2) want to load stylesheets later, (infoPanel example)

Then Boris made his reply (above).

Then you suggested adding the script to the DOM. Boris already
explained that this will have a different effect in Gecko. The only
stylesheets that block scripts are ones that the parser knows about;
using createElement to build and insert a <link> nto the DOM won't
block script execution.

Does your advice work in any browser? I think that it does not, but I
would be interested to know.

> On Mon, 9 Feb 2009, Garrett Smith wrote:
>> In browsers that do not support defer, the scripts must be loaded before
>> subsequent content is loaded. The scripts will block content from
>> rendering below. Scripts will also prevent download of linked
>> stylesheets that appear after in the source. This type of design would
>> also have a negative effect on browsers that do *not* support defer
>> because it means that the scripts appear first, before any linked
>> stylesheets, and cannot be included at the bottom (which is common to do
>> for performance reasons).
> Right, but... so would your proposal, no?

It is unclear what you are asking.

> Incidentally, you'll find that your proposals will probably get further if
> you write shorter, less argumentative, and politer e-mails.

Please try and stay focused and on-topic.

> On Thu, 12 Feb 2009, Boris Zbarsky wrote:
>> I'm proposing flagging scripts that don't depend on stylesheets
> It seems like it is likely that such a feature would end up used before it
> works, with the result being that implementors get forced to not support
> it (a typical "race to the bottom" seen in browser implementation).

In practice, some browses will run a script before a stylesheet loads.
The examples I have shown, Opera and Webkit indicate this behavior,
and can be seen in the title of the document "bgColor = transparent".

Boris' idea would fit into depends as:-


when depends is empty string, it indicates that the script depends on
nothing else.


> --
> Ian Hickson               U+1047E                )\._.,--....,'``.    fL
> http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
> Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

More information about the whatwg mailing list