[whatwg] Proposal for separating script downloads and execution

Kyle Simpson getify at gmail.com
Tue Feb 15 12:29:19 PST 2011


> Although I'm not aware of anyone wrapping a 250KB style-sheet in
> comments, the pre-loading interface could seemingly be applied to any
> number of elements.  Nicholas' original e-mail referenced a blog post
> by Stoyan Stefanov which details a way to pre-fetch both scripts and
> stylesheets.

It's true that many developers have created various tricks for dynamically 
loading stylesheets. Since the <link> element doesn't fire an event when the 
stylesheet finishes loading, they've resorted to a number of hacks, usually 
related to polling some DOM element's calculated style to see if the 
stylesheet has been applied yet.

However, I haven't seen nearly as many people who are wanting to "preload" 
stylesheets (that is, load them but not have them applied). That doesn't 
mean it's not a valid use-case (it very well might be), but I don't see 
there's nearly as much evidence of people doing that as there is for the 
current use-case under discussion (preloading scripts). I do see that 
there's a pretty common use-case where they want to be able to load a script 
element, and be notified with a normative event when the stylesheet 
finishes, so they can execute some further JavaScript logic. But that's 
quite different from saying that they need to "preload" stylesheets.

If you're suggesting that we broaden the scope of this discussion to also 
include the use-cases for preloading of stylesheets, then I think that is 
not a good idea. I understand the desire to solve "preloading" in a 
*consistent* way (I will address that further in a moment) that would work 
for other resource types, but this discussion thread is already quite 
over-weighted with discussions just about scripts. Introducing stylesheets 
into the mix may very well cause the discussion to cross the tipping point 
into unmanageable.

Besides, if we're talking about adding stylesheets into the list of 
resources that should support preloading, why not open the conversation up 
to all types of media: images, video, audio, favicons, etc. I don't see why 
if we're going to broaden the scope of the discussion, we wouldn't just talk 
about all of those different containers' preloading mechanisms.

For the sake of discussion though, let's examine stylesheet preloading 
briefly: there's no reason that stylesheet preloading couldn't work exactly 
as I'm describing (my proposal) for script preloading. In fact, if we're 
looking at the broader context of resource preloading, there's even more 
precedent for doing it this way, when we consider that this is how Image 
preloading has worked for ages. Images are preloaded when the element's 
`src` is set, but are obviously not rendered until added to the DOM. If 
we're going for consistency, I'd say this is even more evidence for my 
proposal.


> Requiring authors opt-into the behavior seems best at least in the
> short term and readyState does not provide this mechanism.

I haven't seen any arguments which suggest that requiring an author to 
opt-in to preloading is necessary to avoid problems. Authors don't/can't opt 
into it in IE, nor does the spec currently give authors any way to opt in or 
out of the behavior, if the browser implements the current spec suggestion. 
Is there any evidence of any compat issues if a resource is preloaded? I've 
not see any valid examples, only speculation about possible/theoretical 
issues.



> Making RPC
> or Ad calls can require disabling this functionality in IE and create
> quite a kluge. (1)

I'm sorry, I don't understand this claim at all. Can you elaborate?


> OTOH, with readystate, the
> tendency will be to add logic for both "preload" and "onload" into a
> single handler,

This is a completely specious argument. You have no evidence that the 
responsible few web authors (in the resource-loading toolset community) who 
are advocating for preloading are going to act irresponsibly and overload 
event handlers in a way that is going to lead to further breakage. And even 
if someone did that, it would easily and obviously break, and they'd be 
shown up for doing it wrongly, whereas the others of us in the 
resource-loading toolset community who do it correctly will be shown to have 
implemented it as intended.

I've said before, I think it's a bad idea to make decisions based upon 
speculation about how bad habits of some of the development community will 
abuse something. Perhaps that prevailing line of pessimistic reasoning was 
applicable 10 years ago, but I chose to believe optimistically that in 2011, 
as the community works much more closely (this thread is proof!) with the 
spec process, quality improvements to the HTML technology/implementation are 
achievable, which will be used responsibly by those who are informed, for 
greater good, than by those who are ill-informed and do it wrongly.


> Most concerning, however, is that adopting readyState will undoubtedly
> create compatibility issues.   It's quite common to registerfor both
> onload and onreadystatechange, testing for the readyState property
> within the handler.  Code like this will execute callback() twice.
>
>    script.onload= script.onreadystatechange= function(){
>              if(
>                    this.readyState  &&
>                    this.readyState != 'loaded' &&
>                    this.readyState != 'complete'
>                ) return;
>
>             callback();
>    }

I've examined the source code of a number of popular script loaders which do 
"onload" / "onreadystatechange" overloading as you depict. Indeed, LABjs has 
always done so. The prevailing best-practice pattern has been that pattern, 
because IE did not add script.onload until IE9 RC. In fact, I believe Steve 
Souders was one of the first to publish code using that pattern, and most of 
the rest of us have followed suit for the last several years.

However, completely ignoring the preloading proposals on the table for the 
moment, that code snippet has an existing vulnerability not at all related 
to IE's "preloading" behavior. There's already a case (related to Opera) 
where the handler can be fired twice. As such, LABjs, and the other 
responsible script loaders I've examined, already keep a boolean flag to 
make sure the handler is only ever processed once. Since that's already an 
existing issue, it's moot to suggest that it's a weakness going forward --  
all script loaders that are going to take advantage of preloading are almost 
certainly already taking care of that niche detail.


> Specifying IE's  behavior (which most will admit seems
> non-intuitive) would also seem to be difficult.

I don't think it's non-intuitive since it's spelled out pretty clearly in 
the spec, AND since that's how Image preloading has worked forever.


> (1)  I do think it's wise to give user-agents the latitude to decide
> the default behavior that works best for their audience.  Instead of
> defining the default value for preload, should the value reflect
> agent-specific default?  IOW, if IE implements this, should its
> default preload value be "true"?

As I've mentioned in an earlier message, the problem with these defaults is 
that it's not being proposed that `preload` be a binary "on" or "off", but 
instead be an "on" or "maybe on" type of property. Are you suggesting that 
browsers should be able to decide what they do in the "maybe on" case, or 
are you suggesting that they should get to decide whether they default to 
"on" mode or "maybe on" mode? Or are you suggesting that they should get to 
decide between "on", "maybe on" and "definitely off"?


> (2) A cached script will have its readyState set to "loaded" when the
> src attribute is assigned, but will not fire the readystatechange
> event.

This is incorrect. I thought that at one point earlier in the thread (even 
filed an IE bug), but it turns out I was incorrect. I've now verified in 
IE6-9 that it properly fires the `onreadystatechange` handler, as expected, 
regardless of if the script is in the cache or not.


> Attaching the script triggers synchronous execution, fires
> readystatechange, but does NOT set the readystate to "complete".

This is also incorrect. Again, the test-case I have works properly in IE6-9, 
in both cached and non-cached states, and fires for both 
`readyState==loaded` and `readyState==complete`, as expected.

http://test.getify.com/ie-script-readystate/



--Kyle 



More information about the whatwg mailing list