Dynamic loading of javascript files into web pages

J

Jorge

I just posted how some browsers handle `with`-based global-eval (as well
as its indirect calls) a couple of days ago earlier in this thread -
<http://groups.google.com/group/comp.lang.javascript/msg/d73710c7cfbd1d7e>

The only difference in `globalEval` from my tests (comparing to yours)
is that I used `with` at load time and you did so at runtime. I don't
see a reason to continuously augment scope when doing so once is enough.

var global = this;

// load time scope chain augmentation
with(global) {
   var globalEval = function(str) {
     return eval(str);
   };

}

// runtime scope chain augmentation
var globalEval = function(str){
   with(global) {
     return eval(str);
   }

}

Latter one is probably slower as well.


All of these are non-standard. All need to be tested before attempting
to use them. I remember there were some problems with `setTimeout(fn,
0)` but can't remember exactly which ones right now.

Ok. Thanks.

Do you like this one ?

6.- Function('return eval('+ 'code' +')')();

or even:

7.- Function( 'code' )();

:)

What other eval-like methods exist ?

-eval(),
-setTimeout,
-Function(),
.... ?
 
G

Garrett Smith

Richard said:
Jeremy J Starcher wrote :

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
We do know that requesting an external script resource will block the
HTML parser. 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.

A browser could follow the standard, and when parsing a script with the
absence of DEFER and ASYNC, load it asynchronously. That is sort of a
technical "loophole" that, if implemented, would break a lot sites.

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

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

Really? Why can't browser eagerly parse to look ahead?

If the browser has not finished downloading the LINK'd stylesheet, it
may opt to not interpret the script. Firefox chooses this option. 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.

In Firefox <= 3.1, a script that follows a LINK'd styleSheet will not
load until the stylesheet loads.
sheet, there is no reason in the world why it should do anything to
interrupt that process.


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.

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.

For stylesheets in the HEAD, browsers will wait for the stylesheet to be
interpreted before rendering the document. This means a LINK can
effectively be another "blocking resource".
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 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.

An HTTP request for a script and the execution of that script are two
completely different actions. It is not necessary to couple these.

To test if this happens, we try including the scripts in various ways,
either by direct include, document.write, or dynamic insertion, and not
usind ASYNC or DEFER.

Each technique can be used on three scripts, effecting a delay on the
second. The delay is created by server processing (Thread.sleep does
it). The scripts should execute serially, but can be requested
asynchronously.

Test Approach:
The server-generated script outputs a "time request received" for each
script. Subtract the third "time requested" from the second. If the time
difference is less than the programmed delay, then the browser made a
predictive fetch of the script resource.

No standard nails down load order, so there is no guarantee of any result.
That using - document.wirte - results in asynchronous script downloading?


While I would be suspicious anyone writing/talking on this subject who
did not publish there full methodology, resulting data and the reasoning
behind the conclusions that they drew from it. Browser scripting is
already plagued with far too many mystical incantations and cargo-cults
for anyone to start jumping through new hoops before seeing some
scientific method backing up the need to do so.

I'm looking at the video and Example 4, aka "The Best One":-

var domscript = document.createElement('script');
domscript.src = "menu.js";
domscript.onloadDone = false;
domscript.onload = function() {
domscript.onloadDone = true;
init();
};

domscript.onreadystatechange = function() {
if ( "loaded" === domscript.readyState &&
! domscript.onloadDone ) {
domscript.onloadDone = true;
init();
}
}
document.getElementsByTagName("head")[0].appendChild(domscript);


- and wondering: Is there a circular reference to watch out for between
the script and the function? e.g. I see no:-

script.onreadystatechange = domscript.onload = null;

- after init.

Is there a race condition here, too? Could
|domscript.onreadystatechange| become "loaded" before
|domscript.onload|? Ouch. Method init() is called twice, with different
conditions in each.

Why not use a variable instead of |domscript.onloadDone|? I can't see
justification for that expando, when it would be safer and easier to write:-

var isDomScriptLoaded = false, or something like that. Expandos are easy
to avoid.

Please see the "cuzillion" site for more.

http://stevesouders.com/cuzillion/
http://stevesouders.com/cuzillion/help.php#examples

Quirks mode can affect the outcome of the tests. Also:
http://stevesouders.com/efws/links.php?ex

Garrett
 
G

Garrett Smith

Conrad said:
I don't think that's necessary. The only person who frequently asked
this question is Jorge, and he won't need an FAQ entry about it. He's
promoting some links/videos which he considers valuable, and I don't
think he'll stop until he receives a plausible explanation.

Jorge, I see what you're doing, and I understand the motivation, but
adding the same list of links after every repost of FAQ 3.2 isn't going
help much. I suggest you make a separate post about these links, and ask
why they shouldn't be included in the FAQ. Maybe we'll get some kind of
review out of that thread. Personally, I've become a bit disillusioned
by Douglas Crockford's idea of the "Good Parts" of JavaScript. This is
mostly due to what I've seen on the JSLint mailing list.


Thanks for transcribing the video, but usually bloopers are ommitted
from a transcription. Reproducing them verbatim ("menu jay") doesn't
really serve any purpose, unless you want to discredit the speaker.
Giving a presentation without making mistakes is a LOT harder that
writing a piece of text.

Transcribing "menu jay" is *not* an attempt to discredit Steve's
speaking ability. It is evidence that the technique couples the
implementation to the abstraction. AISB, a flagrant violation of SRP.
JFTR, I don't recommend this technique either. The fact that it's
invalid HTML is reason enough for me. AFAIK, neither Souders nor Resig
actually use it anywhere. As far as I'm concerned, it's just an
experiment, and shouldn't be given so much attention, and Souders
shouldn't present it as a viable way to improve preformance. He has
other, much better solutions for loading scripts asynchronously.

As mentioned, combining scripts and minifying does a lot.

Moving the script to the bottom helps, too. A bottom script is used with
event bubbling, obviates the (mis)perceived need for a document ready
function.
What's so bad about a calling a separate function to do the eval()? This
will make sure that the JS string is always evaluated in global context,
and it also keeps the 'eval' out of the loader code, which makes
minification easier:

No, ah, as shown in the prior example, the context is global, yes, but
the scope is the scope of the containing context.
function evil (code) {
return eval(code);
}

// later...
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
// ....
evil(xhr.responseText);


This is why we use settings/flags for these optimizations: turn them off
during development and bugfixing, turn them on in production (assuming
that the optimization won't create any bugs by itself). Some library
(Dojo?) automatically adds a comment line at the end of script files to
help in debugging, and I recently read a blog post where somebody
suggested that these hints should be standardised (for debuggers like
FireBug). Can't find the link right now, might have been on Ajaxian.

Similar hints could be added to the example above:

function evil (code, url) {
if (url) {
code += "\n// source: " + url;
}
return eval(code);
}

// later...
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
// assuming scriptURL was set earlier:
evil(xhr.responseText, scriptURL);


It may be more complex, and less clear, but performance tweaks often
are. There's always a tradeoff. I don't think his example code is usable
as-is, but his overview of techniques and the analysis of current
browser behaviors is interesting.

I am not sure that his analysis is completely correct.

Two slides at the end of the
presentation ("impact on revenue" and "cost savings") indicate that for
some companies, at least, the added complexity may well be worth it.


But at least it's valid, and it should be well enough supported, as long
as XHR is available. I'm actually using this technique in a small
project since April (about 80 users, not in a LAN environment), just to
see if there are any practical problems with this approach. If there
were, the XHR injection could be turned off by flipping a config
setting, but so far it hasn't been necessary.

A <script> in the HTML is loaded and run synchronously. Async XHR ->
eval( responseText ) is not. The difference between these two could
significantly affect program behavior and that would affect debugging.
I thought he said there was no single "best" solution. Anyway, the
expandos shouldn't hurt if you choose their names carefully, and you
could easily implement the same thing without expandos if you think they
are that dangerous.
| Probably the best one is ah, script onload. Most of you were thinking
| from the beginning "oh, well the way to do this is script onload".

If the FAQ had a more comprehensive book list, okay. But as long as that
isn't the case, why single out this book as "bad advice", and ignore all
the other books which couldn't be included in the FAQ because they
contain errors?

I do not mean that the book is bad, but Steve's advice on application
design is bad.

Regarding other books, they ought to be removed.

About six weeks ago, I submitted a detailed errata report for "The Good
Parts" on O'Reilly website, regarding page 113. I was careful and reread
it to be clear and correct. When I recently checked the errata site, the
feedback I left was not found.

http://oreilly.com/catalog/9780596517748/errata/

Not in "Confirmed Errata", nor "Unconfirmed Errata". Just gone.

The section (on Functions) is so significant and so wrong, that that
alone should have disqualified the book as being recommended. Functions
are one of JavaScript's best parts. Unfortunately, the book's
explanation is wrong and the correct errata is incorrectly missing.

Garrett
 
J

Jorge

Garrett said:
(...)
About six weeks ago, I submitted a detailed errata report for "The Good
Parts" on O'Reilly website, regarding page 113. I was careful and reread
it to be clear and correct. When I recently checked the errata site, the
feedback I left was not found.

http://oreilly.com/catalog/9780596517748/errata/

Not in "Confirmed Errata", nor "Unconfirmed Errata". Just gone.

Well done. You probably deserve it.
What's that's wrong in your opinion ?
The section (on Functions) is so significant and so wrong, that that
alone should have disqualified the book as being recommended. Functions
are one of JavaScript's best parts. Unfortunately, the book's
explanation is wrong and the correct errata is incorrectly missing.

As arrogant, conceited, bigoted, as always, pretending to know better.

Until you write for us -if ever- the perfect book on JavaScript -in the
meantime- we can do with imperfect ones, thanks.
 
J

Jorge

kangax said:
Jorge said:
Jorge wrote: [...]
sure executed asynchronously, and (1) ought to be executed
asynchronously too. 2,3,5 execute synchronously and can return a value
to the current context. 1,4 can't. So, which is better ? Is there
any 6 ?
All of these are non-standard. All need to be tested before attempting
to use them. I remember there were some problems with `setTimeout(fn,
0)` but can't remember exactly which ones right now.

Ok. Thanks.

Do you like this one ?

6.- Function('return eval('+ 'code' +')')();

or even:

7.- Function( 'code' )();

var globalEval = function(str) {
return Function('return ' + str)();
}

Note that when using these "techniques", evaluating something like
`arguments` will return function's arguments object; an object which
wouldn't normally exist in global scope :)

Yes, indeed. But it's beauty is that while it's a top-level f() it
doesn't require a global symbol...
 
G

Garrett Smith

Jorge said:
Well done. You probably deserve it.
What's that's wrong in your opinion ?

I have linked to a shorter, rougher summary on that, which I cleaned up
and submitted as errata:-
http://groups.google.com/group/comp...9ab113aa05c/3987eac87ad27966#3987eac87ad27966

Richard Cornford dropped in that same thread and also provided an
explanation about Functions.

This came up earlier.
As arrogant, conceited, bigoted, as always, pretending to know better.

Hey, I took time to write that.

If I am "pretending to know better," then what did I write that is
"pretend"?

The errata I submitted, I took care to be accurate and to the point.

I really don't know what happened to it. I do know that I won't be
spending more time to submit errata to "The Good Parts." If I do publish
them, I will publish them here.

The section on "Function Statement vs. Function Definition" will either
be corrected or will not be corrected at all. If it is corrected, it
will probably be corrected sans credit. Really, I don't see either
outcome as positive; either outcome seems conceited and arrogant.

Anyone, including Douglas Crockford, may attempt to refute my arguments
that have been stated on this NG.
Until you write for us -if ever- the perfect book on JavaScript -in the
meantime- we can do with imperfect ones, thanks.

The written word is powerful, and online publishing is far superior.

Writing books impresses those who don't know things about the topic.
There are several advantages to online publishing.

So although I am not a fan of books, and less of a fan of javascript
books, I can say that I dislike books that advocate falsehoods and
misconceptions and I dislike an arrogant author attitude of ignoring
valid criticism.

I can see evidence of this misconception being applied right in the
source code for GMail:

| <script>
| try{function e(b){throw b;}var
| h=true,j=null,k=false,aa=encodeURIComponent,aaa=JS_OBFUSCATED,
| ba=Object,l=Error,ca=parseInt,da=parseFloat,baa=Function,ea=GLOBALS,
| fa=decodeURIComponent,ga=isNaN,m=Math;function caa(b,a){return
| b.appendChild=a}function ha(b,a){return b.textContent=a}function

....

The divergence in having a Function Definition inside a try will result
in two or three different interpretations in top browsers.

Garrett
 
G

Garrett Smith

Garrett said:
Conrad said:
On 27/06/09 10:01, Garrett Smith wrote:
[...]
What's so bad about a calling a separate function to do the eval()? This
will make sure that the JS string is always evaluated in global context,
and it also keeps the 'eval' out of the loader code, which makes
minification easier:

No, ah, as shown in the prior example, the context is global, yes, but
the scope is the scope of the containing context.

Correction, AISB:
| The eval function uses the calling context's [[Scope]], Variable
| object, and |this| value.

The context is global with a function called with no base object, as in:-

function wrappedEval(code) {
var i = 10;
eval(code);
window.alert(i);
}

wrappedEval("var i = 0;");

Garrett
 
J

Jorge

Richard said:
(...)
1. The making of the HTTP requests.
2. The receiving of the HTTP response (the 'downloading').
3. The tokenising/parsing/compiling of the received script.
4. The global variable instantiation and then the execution of
the global code for the complied script.
(...)

There is no reason why steps 1 and 2 could not be performed
concurrently for multiple script resources, as could step 3 (which could
also overlap step 2 as it should be possible to start the
tokenising/parsing/compiling process as soon as source text starts to
become available).
(...)

That's exactly what Safari 4 does now, that no browser did before.

And that's exactly the behaviour that is triggered on in older browsers
by dynamically inserting the <script>s.

See it by yourself:
http://jorgechamorro.com/cljs/071/
 
J

Jorge

Richard said:
Which is "exactly what Safari 4 does now"?


There are "older browser" where scripts cannot be dynamically inserted
at all.


I have seen it; it displays texts and numbers but shows nothing.

It shows that Safari 4 loads the scripts in parallel:

(1).- when dynamically inserted:
http://jorgechamorro.com/cljs/071/1.png

(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

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

HTH,
 
J

Jorge

Jorge said:
It shows that Safari 4 loads the scripts in parallel:

(1).- when dynamically inserted:
http://jorgechamorro.com/cljs/071/1.png

(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

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

HTH,


Look carefully in 1,2,3 and you'll see how the latency time (light
orange) goes by in parallel instead of adding up such as in 4.png

That alone is reason enough to expect an overall speed up, the speed up
that those "text and numbers" show.
 
J

Jorge

Richard said:
<snip>

Repeatedly asserting that it does show something does change anything.

Yes, that's ~ what Goebbels used to say.
If it really does show anything it really should not be that difficult
for you to state _how_ it show that.

Yes, it shouldn't.
 
T

Thomas 'PointedEars' Lahn

Richard said:
^^^^^^^^
Is that '~' and 'approximately' or a 'NOT'?

Since Godwin's Law has been confirmed already, all that is left to be noted
is that probably there was a `not' missing in your first statement.

It is quite reassuring to know that one's filters are properly adjusted.


PointedEars
 
J

Jorge

(...)
So in what way does evidence of "on overall speed up" represent evidence
that "using document.write ... allows concurrent loading"? Which was the
assertion that I called for evidence for and you  then proposed your
page as providing that evidence.

Sure. LOL. Re-read the thread : you've been arguing from the start -
against everything- not only that (that isn't my point, BTW). Now,
you're stepping back and pretending that it's *only* with
document.written <script>s that you've got arguments with ? Ok, try to
cheat, never mind, but re-read this, because I've told you before
already :)

http://groups.google.com/group/comp.lang.javascript/msg/43acc3fdc5be12f8
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++
Using - document.write - really should not do that, and I would be
massively suspicious of any evidence that it does.


Times are changin', see it by yourself:
http://jorgechamorro.com/cljs/071/
In at least Safari 4, FF3.5b and Opera 10b.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++

See:
Safari 4: document.written:
http://jorgechamorro.com/cljs/071/2.png

FF3.5b: document.written:
http://jorgechamorro.com/cljs/071/5.png

Opera 10b: document.written:
http://jorgechamorro.com/cljs/071/6.png

So, yes, they might be (down)loaded in parallel even when
document.written, although that's *not* the point of this thread.
 
J

Jorge

Richard said:
kangax said:
Richard said:
kangax wrote:
Richard Cornford wrote:
kangax wrote:
Richard Cornford wrote:
On Jun 29, 1:21 pm, Jorge wrote:
<snip>
"By making them dynamically declared script elements
(either using document.write or dynamic SCRIPT elements),
it allows **concurrent**loading** with other elements."

Where is the evidence for this?

AIUI, the evidence can be observed by using any of freely
available tools [1][2][3] that allow to view browser
resource requests. More specifically, start/end time
together with an order of those requests is what gives
an overall picture (e.g. [4]) and allows to draw certain
conclusions and/or determine some kind of a pattern.
<snip>

A listing of (some of) the tools that may be employed in
performing experiments that may provide evidence does not
represent evidence of anything.

Of course not. IIRC, the tests itself are provided on
Steve Souders' website.

I did not see any tests on that site that even attempted to
provide evidence that "using document.write ... allows
**concurrent**loading**".

I don't have much time at the moment, so can't look for an
exact test. I do remember vaguely that I've seen
document.write'ed scripts being downloaded concurrently in
some browsers.

Haven't I sufficiently stressed the point that downloading and 'loading'
are not necessarily the same thing; that there is more to a script being
in a 'loaded' state than just having its source text delivered to the
browser?

I have observed script downloads provoked by - doucment.write - use
overlapping (implying that they are at least partly happening in
parallel), but I have also observed the constraints on that behaviour
that are implied by the need to impose some order on the timing and
context of script variable instantiation and global code execution. And
these constraints are at odds with the assertion that "using
document.write ... allows **concurrent**loading**", which serves to make
that assertion sufficiently suspicious as to warrant those making the
assertions taking some meaningful action to back them up (or, at least,
being asked to do so if they can).

Before any of this could move forward there would have to be
some agreement on what "loading" represented when applied to
external script resources. I think a reasonable summation of
the "loading" process might be:-

1. The making of the HTTP requests.
2. The receiving of the HTTP response (the 'downloading').
3. The tokenising/parsing/compiling of the received script.
4. The global variable instantiation and then the execution
of the global code for the complied script.

The inculcation of step 4 may be disputable, but when speaking
of 'loading' a script most would have the expectation, for
example, that the global functions be available (and their
prototypes set-up) once the script had loaded. Making the
inclusion of the global variable instantiation and execution
of the global code a reasonable candidate for inclusion in
the process of "loading". Once all these actions hav

I'm failing to see how global variable instantiation is
relevant here.

Global variable instantiation is where, for example, the
functions resulting form function declarations come into
existence. It must (or at least the system must behave as
if it does) happen before the execution of global code, and
so before the script achieves the state of being 'loaded'.

I see what you mean now. I thought of this step as part of an
actual script execution (i.e. evaluating it as a Program),
since AIUI, ES3 evaluates function declarations during variable
instantiation and variable instantiation probably happens right
after creation of a global object and setting that Global
Object to be a Variable Object.

[...]

You have cut the place where I asked you what you meant by "loaded",
which is a pity because if we cannot agree on what we are talking about
we risk wasting a lot of time talking cross-purposes.

LOL. Nice try: now pretending to shoehorn the meaning of "concurrent
load" into: downloaded+parsed+tokenised/compiled... + executed (!) in
parallel (!)... nothing else ?
 
J

Jorge

Tokenising comes before parsing.


In what sense is that "now pretending", as I laid it out in as many
words earlier?

Is it reasonable for you to be complaining about my being specific about
what I am talking about given the number of times you had previously
been asked to explain what you have been talking about, and declined the
invitation?

Better yet, why did you wait until today to let us know about your
very peculiar idea that the meaning of the verb "to load" is "to load
+ to parse + to compile + to execute" ?

:)
 
J

Jorge

"Can be considered" implies also 'does not need to be considered', and
if you do want to consider it part of parsing than your list is still
wrong as then "tokenising" should not appear in the list at all. If it
does appear in the list (as it does in yours) its correct place in the
sequence is before parsing.

Not necessarily: a text can be parsed but not tokenized, but it can't
be tokenized unless it's parsed as well.
 
J

Jorge

Richard said:
It was the first opportunity I had to devote the time necessary to give
Kangax the answer he deserved. Kangax is worth some effort as, unlike
you, he is willing to engage in a reasoned two-way discussion.

BS. You know that since the very beginning we've been using the word
"load" with the -perfectly valid- meaning of (down)load:

http://groups.google.com/group/comp.lang.javascript/msg/67562c9c3e4afcaa

***************************************
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.
IIRC, The "Why Slow" Or 'yslow' extension for Firefox demonstrates
this.

That using - document.wirte - results in asynchronous script
downloading ?
^^^^^^^^^^^

****************************************

ISTM that what happens here is that everything you've been arguing (1)
so far has been refuted, so you're seeking a way out of the embarrasment
you've get yourself into, by playing with the meaning of words.

(1) to name a few:

- That document.write can't trigger parallel downloads.
- That parallel download can never happen before the document onload
event, no matter what (because the browser is still in the parsing phase).
- That parallel downloads don't speed up nothing, that -in the best
case- it's only "perceived so". (you forgot to consider latencies adding
up and servers that throottle the responses)
- Etc.
 
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.

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

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

Forum statistics

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

Latest Threads

Top