Richard Cornford wrote:
> Garrett Smith wrote:
>> Richard Cornford wrote:
>>> Jeremy J Starcher wrote :
>>>> Thomas 'PointedEars' Lahn wrote:
>>>>
>>>>> neilc wrote:
>>>>>>
>>>>>> Which I've placed into the <head> element of my html page.
>>>>>> The idea is to speed up the loading of the javascript into the page.
>>>>>
>>>>> By loading more script code? Think again.
>>>>
>>>> Although I have not run my own tests, there are a number of
>>>> timing tests out there that indicate many browsers will load
>>>> script elements embedded in the HTML one at a time, blocking
>>>> all other IO until the script is loaded.
>>>
>>> Can you point to these tests, as I do not believe that they would
>>> show any such thing except by coincidence?
>>>
>>
>> Some of the tests I've seen can be found on steve's site. Here are
>> some others:-
>> http://stevesouders.com/efws/links.php?ex
>
> (Interesting to observe how little regard the author of those tests has
> for valid HTML structure.)
>
That markup puts the browser into quirks mode and depends heavily on
significant error handling capabilities and also quirks mode. What's
with the <link> before the doctype?
Worse:
http://stevesouders.com/cuzillion/
>>> We do know that requesting an external script resource will
>>> block the HTML parser.
>
> That is an oversimplification that ignores some (mostly unhelpful)
> behavioural aberrations. The best that might be said is that requesting
> an external script resource will block _an_ HTML parser (as opposed to
> the implication that HTML parsing (for the single document) will be
> blocked).
>
Alright. What "behavioral aberrations"? Prefetching?
>>> It has to because there is always the possibility (in the absence of
>>> the DEFER attribute) that such a script will perform a -
>>> document.write - and so insert character sequences into the HTML
>>> parser's input (which has to happen immediately following the
>>> closing script tag for the importing element else chaos will
>>> ensue). This does not necessitate blocking IO.
>>
>> A script may have ASYNC or DEFER, allowing the script to be loaded
>> at a later time.
>>
>> From HTML 4.01:-
>> | If the src has a URI value, user agents must ignore the
>> | element's contents and retrieve the script via the URI.
>>
>> But when and how? HTML 4.01 does not define load order.
>
> There is no ASYNC attribute in HTML 4.01.
>
Right.
Still, though, no load order is defined in HTML 4.01.
>
>> We can look at what browsers do. When a browser parses a script
>> tag with a SRC and no ASYNC/DEFER, it interprets a script,
>> downloading it first, if necessary. The interpretation blocks
>> subsequent rendering of the page
>
> Where is the evidence for "blocks subsequent rendering"? Blocking the
> parsing of the document's HTML source can be expected, but are you
> really saying that a browser capable of progressive rendering would take
> the opportunity of, say, a script putting up an - alert - dialog, to
> re-render the contents of the browser window? If true, that should be
> relatively easy to demonstrate.
>
Ah, sorry, no, I meant "blocks rendering of subsequent content."
Could subsequent content be parsed and not rendered?
If the content following a script replaced with something that might
look like a resource, could that resource be fetched?
>> and reading the file from the network (or local cache)blocks
>> interpretation. This is a "de facto" standard where browsers
>> will block on some resources, and they do this because a script
>> may include a meta refresh, document.write, location.replace,
>> or other content that is expected to be run synchronously.
>
> So evidence of concurrent loading of external resources for SCRIPT
> elements created with - document.write - would be evidence of behaviour
> that was in opposition to "de facto" standards regarding the handling of
> such resources (and so evidence of the introduction of new issues).
>
Not at all.
>> Browsers follow a "chain of responsibility".
>>
>>> Consider this scenario; The browser is going to follow the HTTP
>>> restrictions and limit the number of simultaneous HTTP connections
>>> to 2,
>>
>> That is not a restriction,
>
> It is a restriction, even if it is commonly disregarded.
HTTP 1.1 says:
| A single-user client SHOULD NOT maintain more than 2 connections with
| any server or proxy.
"SHOULD NOT" is not a restriction. RFC 2119 has the definition of that.
Did I miss some text somewhere else?
>
>> but for the sake of example, we can assume that.
>>
>>> but the HTML parser is working form a buffer into which the HTML
>>> has been loaded having completed being downloaded so both
>>> connections are available. The parser encounters a LINK to an
>>> external style sheet so it starts to use one connection to
>>> download the style sheet. It could do that asynchronously, so
>>> lets assume that it does. It then encounters a SCRIPT element
>>> calling for an external resource, so it starts to download that
>>> with the second HTTP connection. This may force it to block the HTML
>>> parser, but if it has not finished downloading
>>> the style
>
> Wasn't there some point following my "but if"?
>
It would not be beneficial to interrupt the process of downloading a
stylesheet.
>> Really? Why can't browser eagerly parse to look ahead?
>
> It can, if it can handle the 'going back' that may be necessitated by
> the script doing something like - document.write - or - appndChild -
> (both of which would need to be performed in a then 'passed' context).
>
>> If the browser has not finished downloading the LINK'd stylesheet,
>> it may opt to not interpret the script. Firefox chooses this option.
>
> Which would allow for interactions with an 'up to date' -
> document.styleSheet - object.
>
Yep. That's the reason Boris gave. This reason also appeared on Hyatt's
blog, though ironically, I do not see the same behavior in Safari.
(Boris Zbarsky is a senior Mozilla engineer and a reliable source of
information on Mozilla).
There is no official standard that states that a script should wait for
a stylesheet to load before running and so pages should not expect that.
The behavior exists in Firefox.
>> If the browser does not perform an eager download of the script,
>> it will wait for the stylesheet to be interpreted and applied
>> (and that depends on the stylesheet to be downloaded) before the
>> script will be requested. So, a LINK can effectively block a script.
>
> Maybe it should block the global variable instantiation and execution of
> the global code for the script, but it is not an excuse for holding off
> on downloading/tokenising/parsing/compiling the script.
>
Right. The script could be prefectched. But should the script really be
compiled? How would syntax errors be handled?
>> In Firefox <= 3.1, a script that follows a LINK'd styleSheet
>> will not load until the stylesheet loads.
>
> Fine, but that does prevent concurrent downloading of the external
> resources.
>
>>> sheet, there is no reason in the world why it should do
>>> anything to interrupt that process.
>
> Ah, so my point was that the SCRIPT would not interrupt the downloading
> of the CSS, and your response was that the downloading of the CSS would
> not be interrupted. Making "blocking all other IO until the script is
> loaded" a false statment.
>
In Firefox <= 3.1, the download of the SCRIPT won't happen until the
preceeding stylesheet is interpreted.
>>>> Load four scripts, they load one after another while blocking all
>>>> other elements on the page from loading at the same time.
>>>
>>> Blocking all subsequent elements from loading. There is no reason
>>> to believe that they would block previous elements for which
>>> resources could be downloaded asynchronously, such as style sheets
>>> or image data. And the fact that scripts will have to be downloaded
>>> in tern (or at least handled in turn by the client) suggests that
>>> only one connection needs to be devoted to that task, leaving the
>>> other free for those other resources to be retrieved in parallel.
>>
>> Again, in Firefox <= 3.1, a script that follows a stylesheet will
>> not load until the stylesheet loads.
>
> So, again, the loading of previously requested CSS resources for LINK
> elements is not blocked by encountering SCRIPT elements. Making the
> statement "while blocking all other elements on the page from loading" a
> false statement.
>
>> It is not necessary to download scripts in series to interpret
>> those scripts in series. If the browser has a script in the HTML
>> parser's buffer, it can download that resource.
>
> Yes, but it still has to be careful about the order in which it performs
> global variable insanitation and the execution of the global code for
> those scripts.
>
>> For stylesheets in the HEAD, browsers will wait for the stylesheet
>> to be interpreted before rendering the document.
>
> Rubbish. The infamous "Flash of un-styled content" bug that dogged IE
> for years puts the lie to that overgeneralization.
>
Using "all browsers" would be a generalization (fallacy). Statements
about "all browsers" often are. I did not and would not make such
statement. I meant "some browsers" by "browsers".
[...]
>>>> By making them dynamically declared script elements (either
>>>> using document.write or dynamic SCRIPT elements), it allows
>>>> concurrent loading with other elements.
>>>
>>> Using - document.write - really should not do that, and I would
>>> be massively suspicious of any evidence that it does.
>>
>> SCRIPTs included via document.write evaluate in order. This is
>> not an official standard, but a "de facto" standard. When a script
>> writes a script, as in:-
>> <script>
>> var a, b;
>> document.write("<script src="a.js"><\/script>");
>> document.write("<script src="b.js"><\/script>");
>> </script>
>> <script>document.write("a=" + a, "b="+b);
>>
>> - the script being written is inserted into the document after
>> the closing script tag where document.write was called.
>
> The standard that has something to say about this is the W3C HTML DOM,
> which insists that document-write - writes to the "document stream". The
> implication being that it writes at the point just following whatever
> was last processed by the HTML parser (at least prior to the 'closing'
> of a "document stream"). This can be shown to not be the case, at least
> where IE is concerned.
>
In what way?
>> The dynamically added scripts may be downloaded at any time
>> before they are interpreted. They may be downloaded prior to
>> being added to the document, or they may be cached. When the
>> browser encounters the </script>, the document.written HTML (SCRIPTs)
>> is included and the scripts that were included via document.write
>> will be interpreted in order.
>
> The fist script element in your code above writes two SCRIPT elements,
> with two </script> tags. If "a.js" performs a - document.write - will
> its output follow the first of those </script> tags or the second? (try
> it on IE and at leas one other browser (not including Opera 10 beta as
> that one is more buggy than IE).
>
OK.
I tried: Seamonkey, IE5.5-IE8, Firefox 3.5, Opera 9.6, Safari 4. My test
results indicate that the written script is appended to the "document
stream", with minor differences observed in formatting and/or whitespace
in IE 6 and IE8. IOW, the document.write output occurs sequentially, in
order, regardless of which script it appears in.
Four files
1) nested-write.html - document.writes: "write-1.js.js" and "2.js"
2) write-1.js.js - document.writes "1.js"
3) 1.js - defines var v = 1;
4) 2.js - document.writes |v| + |document.body.innerHTML|
Result text in the document:
================================================== ============
typeof v: number
<script type="text/javascript">
document.write(
'<script type="text/javascript" src="write-1.js.js"><\/script>',
'<script type="text/javascript" src="2.js"><\/script>'
);
</script><script type="text/javascript" src="write-1.js.js"></script>
<!-- written from write-1.js.js -->
<script type="text/javascript" src="1.js"></script>
<script type="text/javascript" src="2.js"></script>
================================================== ============
Source code:
1) nested-write.html:
<!doctype html>
<html>
<head><title>nested write</title></head>
<body>
<script type="text/javascript">
document.write(
'<script type="text/javascript" src="write-1.js.js"><\/script>',
'<script type="text/javascript" src="2.js"><\/script>'
);
</script>
</body>
</html>
--------------------------------------------------------
2) write-1.js.js:
document.write("\n<!-- written from write-1.js.js -->\n",
"<script type='text/javascript' src='1.js'></script>\n");
--------------------------------------------------------
3) 1.js
for(var iii = 0; iii < 100000; iii++) new Date();
var v = 1;
--------------------------------------------------------
4) 2.js
document.write("typeof v: " + typeof v,
"<xmp>" + document.body.innerHTML + "</xmp>");
================================================== ============
>> An HTTP request for a script and the execution of that script
>> are two completely different actions. It is not necessary to
>> couple these.
>
> Beyond the need for one to happens before the other.
>
>> To test if this happens,
>
> Test if what happens?
>
We want to see where (if anywhere) scripts are fetched asynchronously.
>> we try including the scripts in various ways, either by direct
>> include, document.write, or dynamic insertion, and not usind ASYNC or
>> DEFER.
> <snip>
>
> That may be a start, but an absence of precise stamens about what is
> being shown and how it is being shown, prevent the exercise from
> approaching anything 'scientific'.
For each browser, test to see if scripts are loaded asynchronously
* with document.write
* with createElement
This can be accomplished by the snipped testing strategy, could it not?
Garrett
--
comp.lang.javascript FAQ:
http://jibbering.com/faq/