Dynamic loading of javascript files into web pages

D

David Mark

Presumably you are recommending this method as "fastest". You should
also note that in IE 6 at least, the scripts are executed out of
order, therefore it can't be used to load more than one script where
the client might be IE 6 and were the order of script execution
matters.



Firefox doesn't show that.  It's times for 2, 3 and 4 are about the
same.  Whether scripts are actually downloaded in series or in
parallel is irrelevant here, the overall time is about the same. It
might be relevant if other content was involved, but you will need to
do much more testing for that.



But 1 is unusable on the web for reasons stated above. If you truly
want the fastest overall performance, you'll use script tags with
stable links to the script files, that way you maximise the use of
caching and reduce download times to zero.  Even though 4 is slowest
as a one-of, it is possibly fastest with caching.

What your test pages do not measure is the effect of the various
techniques on overall page load performance for different types of
page in different environments.

Anyhow, even a substantial script of 5,000 lines will be less than
30kB when minified and compressed, so download time is almost
irrelevant in the context of overall page download time - most pages
seem to be at least 300kB these days, most of that is not script.

Only pages designed by *severely* incompetent developers. Of course,
that easily qualifies as most.
 
R

RobG

[...]
It shows that Safari 4 loads the scripts in parallel:
(1).- when dynamically inserted:http://jorgechamorro.com/cljs/071/1.png
Presumably you are recommending this method as "fastest". You should
also note that in IE 6 at least, the scripts are executed out of
order, therefore it can't be used to load more than one script where
the client might be IE 6 and were the order of script execution
matters.
Firefox doesn't show that.  It's times for 2, 3 and 4 are about the
same.  Whether scripts are actually downloaded in series or in
parallel is irrelevant here, the overall time is about the same. It
might be relevant if other content was involved, but you will need to
do much more testing for that.
But 1 is unusable on the web for reasons stated above. If you truly
want the fastest overall performance, you'll use script tags with
stable links to the script files, that way you maximise the use of
caching and reduce download times to zero.  Even though 4 is slowest
as a one-of, it is possibly fastest with caching.
What your test pages do not measure is the effect of the various
techniques on overall page load performance for different types of
page in different environments.
Anyhow, even a substantial script of 5,000 lines will be less than
30kB when minified and compressed, so download time is almost
irrelevant in the context of overall page download time - most pages
seem to be at least 300kB these days, most of that is not script.

Only pages designed by *severely* incompetent developers.  Of course,
that easily qualifies as most.

Which I think goes back to Garrett's point that those same developers
will swallow this cruft, then implement it ruthlessly and badly,
believing they are solving an otherwise intractable problem, without
realising it is of their own making.

C'est la vie.
 
D

David Mark

[...]
It shows that Safari 4 loads the scripts in parallel:
(1).- when dynamically inserted:http://jorgechamorro.com/cljs/071/1..png
Presumably you are recommending this method as "fastest". You should
also note that in IE 6 at least, the scripts are executed out of
order, therefore it can't be used to load more than one script where
the client might be IE 6 and were the order of script execution
matters.
(2).- when document.written:http://jorgechamorro.com/cljs/071/2.png
(3).- and even when the .src is hardcoded into the .html:http://jorgechamorro.com/cljs/071/3.png
Firefox doesn't show that.  It's times for 2, 3 and 4 are about the
same.  Whether scripts are actually downloaded in series or in
parallel is irrelevant here, the overall time is about the same. It
might be relevant if other content was involved, but you will need to
do much more testing for that.
but not when loaded in series:http://jorgechamorro.com/cljs/071/4.png
And that most other browsers do the same for (1), but not for (2) nor (3).
But 1 is unusable on the web for reasons stated above. If you truly
want the fastest overall performance, you'll use script tags with
stable links to the script files, that way you maximise the use of
caching and reduce download times to zero.  Even though 4 is slowest
as a one-of, it is possibly fastest with caching.
What your test pages do not measure is the effect of the various
techniques on overall page load performance for different types of
page in different environments.
Anyhow, even a substantial script of 5,000 lines will be less than
30kB when minified and compressed, so download time is almost
irrelevant in the context of overall page download time - most pages
seem to be at least 300kB these days, most of that is not script.
Only pages designed by *severely* incompetent developers.  Of course,
that easily qualifies as most.

Which I think goes back to Garrett's point that those same developers
will swallow this cruft, then implement it ruthlessly and badly,
believing they are solving an otherwise intractable problem, without
realising it is of their own making.

I don't remember that point, but I agree with your assessment. We've
certainly seen this pattern of behavior before. Whatever "Web 3.0"
turns out to be, I hope there will be some barriers to entry to keep
the nuts at bay.
C'est la vie.

oui!

Good thing I didn't disagree as I don't know that one.
 
G

Garrett Smith

Richard said:
(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/
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?
There is no ASYNC attribute in HTML 4.01.

Right.

Still, though, no load order is defined in HTML 4.01.
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?
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.
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?
Wasn't there some point following my "but if"?

It would not be beneficial to interrupt the process of downloading a
stylesheet.
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).


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.
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?
Fine, but that does prevent concurrent downloading of the external
resources.


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.
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.


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.


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".

[...]
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 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,
Beyond the need for one to happens before the other.


Test if what happens?

We want to see where (if anywhere) scripts are fetched asynchronously.
<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
 
J

Jorge

RobG said:
Presumably you are recommending this method as "fastest".

I'm not 'recommending' anything.
You should
also note that in IE 6 at least, the scripts are executed out of
order, therefore it can't be used to load more than one script where
the client might be IE 6 and were the order of script execution
matters.

It's a quite well-known fact that execution order isn't preserved with
(1), neither in IE nor in other browsers.
Firefox doesn't show that.

Yes it does: in Firefox 3.5b, and in Chrome 2.0.x, and in Opera 10b, and
in IE8 too. IOW: TIMES ARE CHANGIN'.
It's times for 2, 3 and 4 are about the
same. Whether scripts are actually downloaded in series or in
parallel is irrelevant here, the overall time is about the same.

It isn't irrelevant as it shows the advantage of using (1) in most
browsers up to the current generation.
It
might be relevant if other content was involved, but you will need to
do much more testing for that.



But 1 is unusable on the web for reasons stated above. If you truly
want the fastest overall performance, you'll use script tags with
stable links to the script files, that way you maximise the use of
caching and reduce download times to zero. Even though 4 is slowest
as a one-of, it is possibly fastest with caching.

Caching benefits too all of the above methods, not only (4).
What your test pages do not measure is the effect of the various
techniques on overall page load performance for different types of
page in different environments.

Anyhow, even a substantial script of 5,000 lines will be less than
30kB when minified and compressed, so download time is almost
irrelevant in the context of overall page download time - most pages
seem to be at least 300kB these days, most of that is not script.

Agreed. But as well, often, it's more convenient or even necessary to
have several .js modules that need or need not to be downloaded
depending on e.g. the authenticated user's priveleges, instead of (or in
addition to) a single, big, monolithic .js file.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,734
Latest member
manin

Latest Threads

Top