[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