- From: David Flanagan <david@davidflanagan.com>
- Date: Wed, 20 Jan 2010 11:58:39 -0800
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. David Flanagan
Received on Wednesday, 20 January 2010 11:58:39 UTC