[whatwg] script async and defer attributes questions and confusion
david at davidflanagan.com
Wed Jan 20 11:58:39 PST 2010
I'm trying to understand the async and defer attributes of the script
tag. Unfortunately, since script execution is so intimately tied up
with HTML parsing, section 4.3.1 is particularly hard to make sense of.
I've got 3 questions, and 3 suggested clarifications to the spec.
Thanks to anyone who can explain these!
First, my questions. Are the following three statements correct? (I'm
only concerned with <script> tags that actually appear in a document,
not those inserted or emitted (via document.write()) by another script.):
1) Scripts without async or defer attributes are executed in the order
in which they appear in the document. They are executed synchronously,
which means that the parser must stop parsing the document while they run.
2) Scripts with the defer attribute, but without the async attribute are
executed in the order in which they appear in the document, but their
execution is deferred until the document has finished parsing. All these
scripts will execute before DOMContentLoaded and the load event are
fired. A deferred script can assume that the entire DOM tree has been
constructed and is ready for manipulation--these scripts do not
generally need to register an onload event handler. A call to
document.write() within a deferred script will blow away the current
document and begin a new one.
3) Scripts with the async attribute are executed as their script content
becomes available over the network, with no guarantee that they will be
executed in the order in which they appear in the document. The only
guarantee is that these scripts will run before the DOMContentLoaded or
load events are fired. Document parsing may or may not have completed
when an async script is run, and a call to document.write() from an
async script will have unpredictable behavior. Though the order of
execution of async scripts is not predictable, the scripts will always
appear to run in some serial order without concurrent execution.
Next, I suggest that the following things in the spec be clarified:
1) After describing the async and defer attributes, the spec promises:
"The exact processing details for these attributes are described below."
I take this to mean "below, somewhere in section 4.3". In fact,
however, the exact processing details are scattered throughout the spec,
and understanding the attributes requires understanding section 9, I
think. It would be nice to note this.
2) The last sentence of this paragraph:
> The second is a flag indicating whether the element was "parser-inserted". Initially, script elements must have this flag unset. It is set by the HTML parser and is used to handle document.write() calls.
made me think that the "parser-inserted" flag would only be set to true
for scripts that were emitted through document.write() calls. That is,
I thought that the parser-inserted flag would be set only in unusual
cases rather than in the most common case. This section should explain
the meaning of the parser-inserted flag. Instead it describes one of the
purposes of the flag, but that purpose is different than the purpose
for which it is used in this section.
3) The algorithm for "running a script" adds scripts to "the list of
scripts that will execute as soon as possible". And 9.2.6 spins the
event loop until this list is empty. But I don't see anything in the
spec that removes items from this list. That seems like an error in the
spec, not just a confusing bit. Furthermore, the fact that this
mechanism is specified as a "list" rather than as a "set" implies some
kind of sequential execution of the scripts. But I don't think any
sequence is meant here.
More information about the whatwg