3. My (and Nicholas's previous) proposal: Script elements are fetched
when
inserted into the DOM[1]. An event is dispatched when the script has
been
fetched, eg. "onfetch" or "onpreload"[2]. A "preload" attribute is
added;
when true, the script will not be executed when the fetch completes; call
script.execute() to run the script.
I strongly prefer this proposal to either of the other two, for what
it's worth. Is the concern that this doesn't degrade as nicely in UAs
that don't support preload or something? If not, what _are_ the
arguments against this proposal? Links to existing discussion are fine
if this ground was already covered.
There are several concerns which, at various times, have been brought up
about this variation of the proposal. As Glenn stated, this was Nicholas'
original proposal, but given those questions and concerns, he has adjusted
his proposal several times. The adjustments he's made to his proposal have
generally been to converge it in the direction of my proposal, at least to
some extent.
To briefly restate some of the issues with the original proposal (as
compared to the alternatives):
1. Not only does IE already have the functionality of my proposal
implemented, but the spec already has this exact wording in it. The spec
already suggests that browsers could/should do exactly this preloading, when
the src is set but the element is not yet appended to the DOM. Moreover, my
proposal draws on existing precedent for `readyState` and
`onreadystatechange`, and the way that Image preloading works.
Put plainly, the original proposal is much further from: a) existing spec
wording; AND b) existing browser implementation; AND c) existing precedent.
The goal (from my perspective) is to come up with the simplest proposal that
serves the use-cases. Simplest being defined in this particular situation as
the least amount of change to the spec, AND the least amount of change to
the browser that has by far the slowest release cycle (IE).
2. The execute() API concept had several other questions that arose, such
as:
a) is execute() sync or async? what does this imply about if the script
being executed itself calls execute() on other script elements, and so on?
b) what does it imply about whether/when the event handler(s) would be
fired? If it's synchronous, are the event handlers also synchronous or are
they async? Are they fired before or after the execute() actually does the
executing of the script element?
c) does this run the risk of going afoul of the same issue that tripped of
Firefox with their synchronous execution of inline script elements (that
jQuery used for global-eval)?
d) what are the semantics of if you call execute() on a script element
before it has finished preloading, or for a script that wasn't preloaded at
all? Does this simply turn off preloading execution-deferral flag? Or does
it throw an error? Would those errors be synchronous (like an actual
exception that aborts processing) or simply bubble to the script.onerror
handler?
e) what happens if a script's .text is modified before execute() is
called? What if a script element is cloned before execute() is called? What
if it's cloned after execute() is called?
3. If in the future we want to also support preloading of other resources,
like stylesheets for instance, which of the proposals offers the best
precedent for that? For instance, would it make sense to add a .execute() to
the <link> element for applying a stylesheet that had been preloaded? Or
would the preloading style from my proposal (or even Nicholas' current
proposal variation) fit more cleanly?
In exploring these issues and questions (and others), some contradictory
arguments were brought up. In the end, I think Nicholas found it easier to
simplify his proposal rather than keep going down this rabbit hole. For the
most part, my proposal doesn't seem to suffer the same complexity of most of
these questions. And to the extent that some of the questions are
applicable, those questions already exist and browsers already have answers
for the normal dynamic script append semantics.
Again, I think the spirit we all share is to find the simplest proposal that
gets the job done, and introducing a new .execute() concept raised more
questions than it purported to solve.
BTW, I don't necessarily claim that above to be an exhaustive distillation
of this entire thread as it related to Nicholas' original proposal, and the
revival of it that Glenn has been pushing for -- I'm sure I missed a few
points in my memory recall. But I do think it's at least illustrative of how
the conversation got a lot more complicated as we started exploring how
.execute() would actually work.
I sympathize with that, since they're aiming to improve the likelihood of
being implemented--but the precedent it's drawing on seems like a bad one,
which should be treated as a compatibility hack rather than a precedent
for
new APIs.
I strongly disagree with this characterization, based solely on the fact
that the wording of the current spec already says to do exactly as I'm
proposing. That's not a "compatibility hack", that's further standardizing
the wisdom that the spec writers already thought through and codified.
I'd like to know what Opera and Webkit folks think, in terms of
implementation difficulty.
FWIW, someone from Opera did, earlier in this thread, at least weigh in to
suggest that they would implement the "readyState preloading" (aka, my
proposal) completely (if they did so at all), to allay fears that Opera
might break the assumption of the feature-detection that my proposal relies
on.
To be clear, they didn't say they'd implement this proposal. But they did
agree that preserving the feature-detect would be prudent, meaning they
wouldn't change their implementation of `readyState` unless they were
bringing it fully in line with IE's behavior (and thus my proposal).
--Kyle