Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dynamic loading of javascript files into web pages

61 views
Skip to first unread message

neilc

unread,
Jun 25, 2009, 11:21:50 AM6/25/09
to
Hello I've got the following code

<script type="text/javascript">

var aScripts = [ "scripts/jquery.js", "scripts/jquery.scrollTo-
min.js", "scripts/jquery.localscroll-min.js" ];

function forEach( array, action ) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}

function loader_( array ) {
forEach(array, function (element) {
var p = document.getElementsByTagName( "HEAD" )[0];
var c = document.createElement( "script" );
c.type= "text/javascript";
c.src = element;
p.appendChild( c );
});
}

loader_( aScripts );

</script>

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. Some pages
load in 10 or so other javascript pages and this really helps.

The problem is that it doesnt want to work properly in IE 6 or Safari
4. Neither browser tells me what the problem is but I just wanted to
know if anyone had any suggestions as to where I should be looking
next.

thanks
Neil

Thomas 'PointedEars' Lahn

unread,
Jun 25, 2009, 11:28:28 AM6/25/09
to
neilc wrote:
> Hello I've got the following code
>
> <script type="text/javascript">
>
> var aScripts = [ "scripts/jquery.js", "scripts/jquery.scrollTo-
> min.js", "scripts/jquery.localscroll-min.js" ];

My condolences.

> function forEach( array, action ) {
> for (var i = 0; i < array.length; i++)
> action(array[i]);
> }

JavaScript 1.7+ (current: 1.8) already as Array.prototype.forEach(), you
should use that where available.

> function loader_( array ) {
> forEach(array, function (element) {
> var p = document.getElementsByTagName( "HEAD" )[0];

Should be lowercase.

> var c = document.createElement( "script" );
> c.type= "text/javascript";
> c.src = element;
> p.appendChild( c );
> });
> }
>
> loader_( aScripts );
>
> </script>
>
> 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.

> Some pages load in 10 or so other javascript pages and this really helps.

Rubbish.


PointedEars

Peter Michaux

unread,
Jun 25, 2009, 1:50:43 PM6/25/09
to
On Jun 25, 8:21 am, neilc <capho...@gmail.com> wrote:
> Hello I've got the following code
>
> <script type="text/javascript">
>
> var aScripts = [ "scripts/jquery.js", "scripts/jquery.scrollTo-
> min.js", "scripts/jquery.localscroll-min.js" ];
>
> function forEach( array, action ) {
> for (var i = 0; i < array.length; i++)
> action(array[i]);
> }
>
> function loader_( array ) {
> forEach(array, function (element) {
> var p = document.getElementsByTagName( "HEAD" )[0];
> var c = document.createElement( "script" );
> c.type= "text/javascript";
> c.src = element;
> p.appendChild( c );
> });
> }
>
> loader_( aScripts );
>
> </script>
>
> 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.

The above script shouldn't be speeding up the process of loading
JavaScript files. The same files are still travelling across the wires
from the server to the browser.

> Some pages
> load in 10 or so other javascript pages and this really helps.

I don't see how it helps. Do you have some definitive tests showing it
does?

> The problem is that it doesnt want to work properly in IE 6 or Safari
> 4. Neither browser tells me what the problem is but I just wanted to
> know if anyone had any suggestions as to where I should be looking
> next.

You've replaced using straightforward, well supported script tags with
a src attributes by the complex and iffy script above. Even had you
not reported problems, I would suspect some browsers wouldn't react
well to what you are doing.

Peter

Peter Michaux

unread,
Jun 25, 2009, 1:57:29 PM6/25/09
to
On Jun 25, 8:28 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

> neilc wrote:
> > Hello I've got the following code
>
> > <script type="text/javascript">
>
> >            var aScripts = [  "scripts/jquery.js", "scripts/jquery.scrollTo-
> > min.js", "scripts/jquery.localscroll-min.js" ];
>
> My condolences.
>
> >            function forEach( array, action ) {
> >              for (var i = 0; i < array.length; i++)
> >                action(array[i]);
> >            }
>
> JavaScript 1.7+ (current: 1.8) already as Array.prototype.forEach(), you
> should use that where available.

I'd say, in this case, if this script has to stay at all, for some
unknown reason to me, then just get rid of forEach as it is bulking up
what is supposed to be a small helper script. Use a for loop in the
loader_ function and avoid the idea of using the native
Array.prototype.forEach all together.

Peter

Jeremy J Starcher

unread,
Jun 25, 2009, 2:46:54 PM6/25/09
to
On Thu, 25 Jun 2009 17:28:28 +0200, 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.

Load four scripts, they load one after another while blocking all other
elements on the page from loading at the same time. By making them
dynamically declared script elements (either using document.write or
dynamic SCRIPT elements), it allows concurrent loading with other
elements.

IIRC, The "Why Slow" Or 'yslow' extension for Firefox demonstrates this.
I forget how they tested the other browsers.

Peter Michaux

unread,
Jun 25, 2009, 3:00:11 PM6/25/09
to HikksNo...@aol.com
On Jun 25, 11:46 am, Jeremy J Starcher <r3...@yahoo.com> wrote:


> Load four scripts, they load one after another while blocking all other
> elements on the page from loading at the same time.  By making them
> dynamically declared script elements (either using document.write or
> dynamic SCRIPT elements), it allows concurrent loading with other
> elements.

I wish Randy Webb was around right now. I've cc'ed him on this
message. He is/was a fan of dynamic script tag insertion at least for
some purposes.

Peter

Conrad Lender

unread,
Jun 25, 2009, 3:30:16 PM6/25/09
to

I suppose that was tongue in cheek, but there are in fact techniques
which can help improve the time it takes to load and render a
script-heavy page. Steve Souders specializes in this area, and his books
about high performance web sites are definitely worth a read. His second
book has only just been released, and I haven't read it yet, but he has
been very generous about publishing pre-release chapters on his blog.

http://www.stevesouders.com/

David Mark will probably kill me right about now, because Steve Souders
works at Google, and nothing good has ever come from that company,
according to David. Nevertheless, IMO there's a lot of interesting
information in Souders's books and on his blog; a good starting point
would be

http://www.stevesouders.com/blog/2009/04/23/even-faster-web-sites/

You don't have to embrace any of the "script injection" techniques he
offers, make your own judgement instead. The analysis about where to put
<style>, <script>, <link> tags, and when different browsers will block
when they encounter such an element is interesting enough by itself.

He's also the author of YSlow, which Jeremy mentioned before.


- Conrad

Thomas 'PointedEars' Lahn

unread,
Jun 25, 2009, 3:47:17 PM6/25/09
to
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.

Works as designed.

> Load four scripts, they load one after another while blocking all other
> elements on the page from loading at the same time. By making them
> dynamically declared script elements (either using document.write or
> dynamic SCRIPT elements), it allows concurrent loading with other
> elements.

And risking runtime errors because required methods and properties are
not yet there, if ever? No, thanks. But wait -- these tests have been
performed by people who are clueless enough to advocate "Unobtrusive
JavaScript" and huge abominations like jQuery, yes?

10 scripts in one document ... o tempora, o mores.


PointedEars

neilc

unread,
Jun 26, 2009, 3:24:33 AM6/26/09
to

Thanks for all the replies, I've created some passionate feelings
here !

Some of you totally missed the point with this and obviously
understand how the web browsers works.

But thanks to Jeremy J Starcher for getting what I meant.

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

This is exactly what happens and this is an attempt to load all
scripts at the same time. If you use firebug and look at the .net tab
you will see how this works.

My tests show that I've consistently saved 1 second by implementing
this method (in firefox and ie7) but as I mentioned ie6 and safari 4
seem barf.

There is a discussion here

http://stackoverflow.com/questions/21294/how-do-you-dynamically-load-a-javascript-file-think-cs-include
and
http://www.artzstudio.com/2008/07/beating-blocking-javascript-asynchronous-js/

For those who do not get it (ie PointedEars)

Thomas 'PointedEars' Lahn

unread,
Jun 26, 2009, 3:54:55 AM6/26/09
to

How typical, script-kiddie. You need to refer to work of
other people because you don't have any arguments yourself.

> For those who do not get it (ie PointedEars)

*You* don't get it. If you continue loading the document while scripts are
loading (if that, all of this is based on the weak assumption that scripts
can be dynamically loaded everywhere), methods that these scripts provide
may or may not be available while the document is loading.

That is not a problem if you follow the ill-advised "Unobtrusive JavaScript"
approach to the letter because then there is no script code in the `body'
element. However, if you follow the standards-compliant and reliable
approach which includes event delegation, event listeners that call methods
that do not yet exist (because the scripts that define them have not been
loaded or not fully loaded yet) cause runtime errors. And because the
scripts may not be loaded in sequential order, if at all, and features of
the scripts are likely not be used in sequential order in the document, it
will work on one element and fail on another. So much for user experience.

Then again, when it has become necessary to load scripts dynamically in
order to create a viable document, maybe, just maybe, there is something
wrong with the scripts, such as size (for including a lot of unused
features, or providing them through unnecessarily extensive method
overloading), or runtime efficiency (for thinking every computer is under
all conditions as fast as the testing system, and for foolishly thinking it
would be faster to add a listener to every element in sight instead of event
delegation)?

And when there are 10 scripts or more in a document, maybe, just maybe,
somebody has not understood a first thing about browser scripting and Web
authoring, and just tries to have their tag soup spiced by including a dozen
script libraries from everywhere, written by equally clueless people?


PointedEars

neilc

unread,
Jun 26, 2009, 4:32:34 AM6/26/09
to
Thanks for you response, this is a much better explanation than your
previous efforts which were rude and unhelpful. I appreciate you
taking the time to explain. You're tone is a quite uptight and
childish, you might enjoy life more if you had some therapy ? Being
nice to people is much more rewarding. You should try it.

From what you've suggested perhaps the best thing to do is try and put
all the scripts in one file perhaps and minify this, rather than the
approach I've taken. Then I could just use a standard include method.

I agree that the scripts/libraries I'm including could have some
excess baggage, but I don't have the time to go through and trim them
so I'm looking at other methods to speed up page loading. Don't get me
wrong - my pages are quite fast anyway and dont provide a problem -
but I'm just looking at ways of trimming a few milliseconds off them.

Jorge

unread,
Jun 26, 2009, 4:40:38 AM6/26/09
to
On Jun 26, 9:24 am, neilc <capho...@gmail.com> wrote:
> (...)

> There is a discussion here
>
> http://stackoverflow.com/questions/21294/how-do-you-dynamically-load-...
> andhttp://www.artzstudio.com/2008/07/beating-blocking-javascript-asynchr...

And a video here: Steve Souders: "Life's Too Short - Write Fast Code
(part 2)", "Advanced script loading: six ways to load scripts without
blocking the page" (starting @10m40s)
http://www.youtube.com/watch?v=52gL93S3usU

DON'T MISS IT: John Resig's über-cool "degrading script pattern",
starting @22m15s.

I wonder why jewels like these don't make its way into the resources
FAQ.

> For those who do not get it (ie PointedEars)

--
Jorge.

Thomas 'PointedEars' Lahn

unread,
Jun 26, 2009, 4:45:33 AM6/26/09
to
Thomas 'PointedEars' Lahn wrote:
> neilc wrote:
>> There is a discussion here
>>
>> http://stackoverflow.com/questions/21294/how-do-you-dynamically-load-a-javascript-file-think-cs-include
>> and
>> http://www.artzstudio.com/2008/07/beating-blocking-javascript-asynchronous-js/
>
> How typical, script-kiddie. You need to refer to work of
> other people because you don't have any arguments yourself.

And, of course, you have selective perception, too:

,-<http://stackoverflow.com/questions/21294/how-do-you-dynamically-load-a-javascript-file-think-cs-include>
|
| I used a much less complicated version recently with jQuery:

jQuery, hm, hm. What was the reason he used jQuery despite considerable
criticism? Cult-like dependency because of cluelessness? I see.

| It worked great in every browser I tested it in: IE6/7, Firefox, Safari,
| Opera.

Extraordinary. Now you need to test all the other browsers out there, dude,
and hope nothing changes about this undocumented feature in the future.

| The technique we use at work is to request the javascript file using an
| AJAX request and then eval() the return. If you're using the prototype
| library, they support this functionality in their Ajax.Request call.

"AJAX request", hm, hm. What if "AJAX" is not supported or disabled?
You don't care for those users? I see.

| i've used yet another solution i found on the net ... this one is under
| creativecommons and it checks if the source was included prior to calling
| the function ...
|
| /** include - including .js files from JS - bfu...@gmail.com - 2005-02-09
| ** Code licensed under Creative Commons Attribution-ShareAlike License
| ** http://creativecommons.org/licenses/by-sa/2.0/
| **/
| var hIncludes = null;
| function include(sURI)
| {
| if (document.getElementsByTagName)
| {
| if (!hIncludes)
| {
| hIncludes = {};
| var cScripts = document.getElementsByTagName("script");
| for (var i=0,len=cScripts.length; i < len; i++)
| if (cScripts[i].src) hIncludes[cScripts[i].src] = true;
| }
| if (!hIncludes[sURI])
| {
| var oNew = document.createElement("script");
| oNew.type = "text/javascript";
| oNew.src = sURI;
| hIncludes[sURI]=true;
| document.getElementsByTagName("head")[0].appendChild(oNew);
| }
| }
| }

Ridiculous. Not only that it doesn't do as advertised (anybody surprised?),
the whole point of asynchronous loading is that execution continues while
the script is loading. Therefore, the existence of the `script' element
(which is not even tested here!) does not mean anything for the loading
state of the script.

(What might work for detection is declaring a variable at the top of the
script and assigning an identifying value to it at the bottom. We have
discussed this before.)

| Just found out about a great feature in YUI 3 (at the time of writing
| available in preview release). You can easily insert dependencies to
| YUI libraries and to "external" modules (what you are looking for)
| without too much code: YUI Loader.

Which follows the same weak assumption, of course. But then YUI is not
designed to degrade gracefully, to follow accessibility guidelines and
legislation and all.

| all the major javascript libraries like jscript, prototype, YUI have
| support for loading script files.

Let's eat sh*t! A million flies can't be wrong.

,-<news:67b42083-9382-4bde...@x29g2000prf.googlegroups.com>


|
| You've replaced using straightforward, well supported script tags with
| a src attributes by the complex and iffy script above. Even had you
| not reported problems, I would suspect some browsers wouldn't react
| well to what you are doing.

Finally, hear the voice of reason.

,-<http://www.artzstudio.com/2008/07/beating-blocking-javascript-asynchronous-js/>
|
| 5. Vladimir Dzhuvinov tipped... September 15th, 2008 at 1:07 am
|
| Hi,
|
| I don’t know how versed your readership is, but in case there are any
| casual readers, it would be good first to explain to them that browser
| interpreters “block” script execution for a good reason:
|
| http://www.mozilla.org/js/language/js20-1999-03-25/execution-model.html
|
| 6. Arup stated... October 7th, 2008 at 4:06 am
|
| This implementation has several disavantages also . Like page timeout
| functionality . Sometimes the ojects are set to null and js not works
| on the page .

Even some people there got it.

>> For those who do not get it (ie PointedEars)
>
> *You* don't get it. If you continue loading the document while scripts are
> loading (if that, all of this is based on the weak assumption that scripts
> can be dynamically loaded everywhere), methods that these scripts provide
> may or may not be available while the document is loading.

> [...]


> Then again, when it has become necessary to load scripts dynamically in
> order to create a viable document, maybe, just maybe, there is something
> wrong with the scripts, such as size (for including a lot of unused
> features, or providing them through unnecessarily extensive method
> overloading), or runtime efficiency (for thinking every computer is under
> all conditions as fast as the testing system, and for foolishly thinking it
> would be faster to add a listener to every element in sight instead of event
> delegation)?
>
> And when there are 10 scripts or more in a document, maybe, just maybe,
> somebody has not understood a first thing about browser scripting and Web
> authoring, and just tries to have their tag soup spiced by including a dozen
> script libraries from everywhere, written by equally clueless people?

q.e.d.

BTW, check out loadScript() from <http://PointedEars.de/dhtml.js>, and
notice the copyright date in the JSdoc ...


PointedEars

Thomas 'PointedEars' Lahn

unread,
Jun 26, 2009, 4:48:59 AM6/26/09
to
neilc wrote:
> Thanks for you response, this is a much better explanation than your
> previous efforts which were rude and unhelpful. I appreciate you
> taking the time to explain. You're tone is a quite uptight and
> childish, you might enjoy life more if you had some therapy ?

*PLONK*

Garrett Smith

unread,
Jun 26, 2009, 9:15:10 PM6/26/09
to
Conrad Lender wrote:
> On 25/06/09 21:00, Peter Michaux wrote:
>> On Jun 25, 11:46 am, Jeremy J Starcher <r3...@yahoo.com> wrote:
>>> Load four scripts, they load one after another while blocking all other
>>> elements on the page from loading at the same time. By making them
>>> dynamically declared script elements (either using document.write or
>>> dynamic SCRIPT elements), it allows concurrent loading with other
>>> elements.
>> I wish Randy Webb was around right now. I've cc'ed him on this
>> message. He is/was a fan of dynamic script tag insertion at least for
>> some purposes.
>
> I suppose that was tongue in cheek, but there are in fact techniques
> which can help improve the time it takes to load and render a
> script-heavy page. Steve Souders specializes in this area, and his books
> about high performance web sites are definitely worth a read. His second
> book has only just been released, and I haven't read it yet, but he has
> been very generous about publishing pre-release chapters on his blog.
>
> http://www.stevesouders.com/
>

Steve Souders advocates practices which require good judgment and design
to avoid maintenance issues. The performance tips and tricks are great,
but can be rather harmful if the implementation of the performance tip
is poor. An application that is poorly engineered is likely to have
performance problems and the developers who created the poor
implementation are likely to have a poor implementation of the tips and
tricks, as well.

Performance tends to be a problem when there is a lot of javascript. The
situation of too much javascript is often caused by using 1+ libraries
that have very general functionality, consisting of largely of
abstractions created to solve a myriad of potential problems. This
situation is common for teams who try to implement a lot of features,
don't know how, and try to "just get it done". I have seen this a lot.

It is easy to do lots of stuff half-assed. In the long run, it will just
cost more (time and money). The code matters!

So what should a who gets themselves in this situation do?

There is no "speed" button or magic solution. Hiring a performance
expert won't change that; it is a cop out that avoids the blame game.

A more practical and proactive solution is to look again at the problem
and look to see if the code effectively and clearly solves the
requirement problem. Continual refactoring, buddy checks (code review)
and pair can help.

Application design and architecture is where performance affected most
and it is most effective when it is simple enough to communicate it.
Communicating the design to others prevents the design from becoming so
complicated that it cannot be communicated effectively, which can help
keep the design simple.

Steve doesn't talk about design or process much From what Steve Sounders
has stated, I have not heard good design advice.

For example, Steve advocates combining scripts together. This will make
the pages load faster by reducing the number of http requests. The
technique works but it has to be done right. Doing it right requires an
explanation of how. I attended a presentation a few years back where an
audience member said they were combining the files together by hand and
wanted to ask for advice on that. Now, copy-pasting is a tedious and
error-prone process, which was my knee-jerk response, however I recall
Steve suggesting the audience member to continue doing that, which
appalled me.

Another example is the advocacy of using fallback content in a script
tag by John Resig. Steve Souders ignored valid criticism by TNO, myself,
among others.

http://ejohn.org/blog/degrading-script-tags#postcomment

Note: To view the comments on ejohn.org, javascript must be enabled.
(grrr).

Steve and John talked about performance in a later presentation where
John discussed the DEFER attribute in a way that are incorrect. Nobody
corrected him. Not even Steve. In a later presentation, Steve Souders
congratulated John Resign on the presentation.

Although the mistake was of John Resig, if Steve Souders is a
performance expert, he ought to have made a correction to the
explanation of how DEFER works. That was discussed here:

http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/df4f80404e12da8f/53a3903684b6f7b9?#53a3903684b6f7b9

> information in Souders's books and on his blog; a good starting point
> would be
>
> http://www.stevesouders.com/blog/2009/04/23/even-faster-web-sites/
>

No knowledge is bad, however, architecture is going to affect
performance most of all.

> You don't have to embrace any of the "script injection" techniques he
> offers, make your own judgement instead.

http://code.google.com/speed/page-speed/faq.html#speed

| Some of Page Speed's recommendations seem to go against certain design
| and development practices. Does Google think that only speed is
| important?
|
| Since Page Speed is a performance optimization tool, its
| recommendations are biased in favor of speed. However, we recognize
| that web development is complex, and our suggestions might be
| restrictive for an individual web site. You have to consider the
| tradeoffs for your own application: some of Page Speed's
| recommendations take substantial effort to implement, so you need to
| evaluate the cost of making changes vs. the benefit the rule would
| have on your page. Our goal is simply to point out the issues that you
| should consider fixing.

The analysis about where to put
> <style>, <script>, <link> tags, and when different browsers will block
> when they encounter such an element is interesting enough by itself.
>


Splitting the initial payload is something Steve hyped but the solutions
he provides miss the point. The problem is that looking at the initial
payload should be the first step. AISB, look at the problem, then at the
code, and analyze.

It would be like going camping and saying, geez, we have to optimize for
space here, because all this crap doesn't fit in my car. Instead, of
saying "all this stuff doesn't fit in my car" and then looking at what
we need and what "all this stuff" is. Instead of jumping to optimizing
how the stuff is packed, it makes sense to see what we need and then
organize that in a sensible way (food in the cooler, tent on the bottom)
and just leave all that other stuff behind (hair spray, etc). YAGNI!

YAGNI YAGNI YAGNI!

I read Steve's first a few years ago and, at the time, thought it was
worth including in the FAQ. If a review of his second book is desired,
then they can send me a copy.

> He's also the author of YSlow, which Jeremy mentioned before.

Right. And now he works at Google and they have Page Speed, which I have
just installed.

I think YSlow and maybe Page Speed ought to be mentioned in the FAQ, but
not under "how to get my browser to report errors". That entry needs to
be split up a bit, possibly to explain:

* Common errors like "Operation aborted", "x is not a function", etc.
* How to turn on error reporting
* Performance tools
* IDEs

>
>
> - Conrad
Psst - sent you mail response. LMK :-)

Garrett

[1]http://code.google.com/speed/page-speed/docs/rules_intro.html
[2]http://oreilly.com/catalog/9780596522308/
--
comp.lang.javascript FAQ: http://jibbering.com/faq/

One Dumm Hikk

unread,
Jun 26, 2009, 9:49:05 PM6/26/09
to
On Jun 25, 3:00 pm, Peter Michaux <petermich...@gmail.com> wrote:
> On Jun 25, 11:46 am, Jeremy J Starcher <r3...@yahoo.com> wrote:
>
> > Load four scripts, they load one after another while blocking all other
> > elements on the page fromloadingat the same time.  By making them

> > dynamically declared script elements (either using document.write or
> >dynamicSCRIPT elements), it allows concurrentloadingwith other

> > elements.
>
> I wish Randy Webb was around right now. I've cc'ed him on this
> message. He is/was a fan ofdynamicscript tag insertion at least for
> some purposes.
>
> Peter

You found me. I have no idea why but AOL put the email in my
spam folder and for the first time in almost 2 months I looked
through it. I guess fate had it that I should see it.

Dynamically loading script files to speed up the loading process?
Garbage.

What it will do, if done properly, is speed up the initial
rendering of the page. But it WON'T speed up load time of the
files and will actually slow it down. The reason it will
actually slow it down is because it has to do more work to
load the files. Whether the file is static coded or dynamically
loaded, the file still has to be downloaded from the server.
Want it to download faster? Make the file physically smaller.
Any other advice is magical hocus-pocus for making it load
faster if everything else is the same.

As for the script posted, it won't speed up page rendering
even if you get it to work. Why? It isn't loading the scripts
after the onload event fires, it is trying to dynamically
load them AS the page is loading. No difference than having
them hard coded in script tags.

Aside from some of the problems pointed out already, there
remains an issue of the way you are calling it. Rather than
calling it inline as you are, assign it to the onload event
handler so that the scripts aren't loaded until the onload
event fires. When the onload event fires, the page will render.

function loader() {


var aScripts = [ "scripts/jquery.js",

"scripts/jquery.scrollTomin.js",
"scripts/jquery.localscrollmin.js" ];

for (var i = 0; i < aScripts.length; i++)


{
var p = document.getElementsByTagName( "HEAD" )[0];

var c = document.createElement( "script" );
c.type= "text/javascript";

c.src = aScripts[i];
p.appendChild( c );
}
}
window.onload = loader;

Then, it won't try to load them until the page has loaded
and that will APPEAR to speed up the page loading but it won't.
It will actually slow down total page load time.

Ever wonder why people think JS is so hard? Because they try to
make it harder than it has to be. KISS - Keep It Simple Stupid.

After all this time, I would have thought TL had exited certain
stages of life but I see he hasn't. Sad.

Conrad Lender

unread,
Jun 27, 2009, 12:30:42 AM6/27/09
to
On 27/06/09 03:15, Garrett Smith wrote:
> Steve Souders advocates practices which require good judgment and design
> to avoid maintenance issues. The performance tips and tricks are great,
> but can be rather harmful if the implementation of the performance tip
> is poor.

Of course. I wouldn't recommend blindly following his recommendations.
Much of it is overkill, and only effective on sites with a lot of
external content (images, css, scripts). Nevertheless I learned a lot
from his articles, and some of the suggestions are very easy to
implement without adding to the complexity: knowing that even very small
inline <script> elements can block page rendering and the fetching of
external resources can lead to a document structure which allows
browsers to do more things in parallel. No magic involved.

> For example, Steve advocates combining scripts together. This will make
> the pages load faster by reducing the number of http requests.

IMHO, this is one of the easiest and most effective optimizations.
Here's a little anecdotal example: I am currently involved in a intranet
project for a federal organization. All workstations are centrally
managed by the IT department, and IE7 is the only permitted browser.
Unfortunately, there are other legacy web applications in use, and one
of them appears to have a problem sending PDF files over SSL. The IT
department's solution was to turn off the browser cache. Everywhere.
Completely and unconditionally, and even the memory cache (this means
that if you have a background-image style set on :hover, the image would
be requested every time you move the mouse over the area). This created
a major performance problem for us, because our pages would include
about 3-4 CSS files and 10-15 JavaScript files, in addition to ~30
images (mostly backgrounds and icons). Download speed didn't matter
(LAN), but IE's two-connection limit and the number of requests did. So
we had to simplify the design, create CSS sprites for the icons, and
concatenate all the CSS and JS files. Nothing we did after that (like
minimization) had anything like the effect that reducing the number of
requests had.

Not everything Souders suggests is equally important to everybody, but
there are situations where it really can help.

> technique works but it has to be done right. Doing it right requires an
> explanation of how. I attended a presentation a few years back where an
> audience member said they were combining the files together by hand and
> wanted to ask for advice on that. Now, copy-pasting is a tedious and
> error-prone process, which was my knee-jerk response, however I recall
> Steve suggesting the audience member to continue doing that, which
> appalled me.

That's just silly, this stuff should be automated, with options to
disable concatenation, minimization, and caching.

> Another example is the advocacy of using fallback content in a script
> tag by John Resig. Steve Souders ignored valid criticism by TNO, myself,
> among others.

Yeah, I read that article. I filed it as an interesting and curious idea
(hadn't occurred to me, at least), but one that had too many problems to
be used in a serious project.

> Although the mistake was of John Resig, if Steve Souders is a
> performance expert, he ought to have made a correction to the
> explanation of how DEFER works. That was discussed here:

Oh, he (Souders) knows how defer works. I can't comment on why he chose
not to correct Resig.

> Splitting the initial payload is something Steve hyped but the solutions
> he provides miss the point. The problem is that looking at the initial
> payload should be the first step. AISB, look at the problem, then at the
> code, and analyze.

I see where you're going with this - architecture/design before
optimizations - but one doesn't preclude the other. Most of the code
loaded on a page isn't very performance intensive (there are
exceptions). I wholeheartedly agree that loading one or more "heavy"
libraries like YUI will have an impact, but for me personally, this is
not an issue, because our libraries contain only (well, almost only)
what's really needed on the page. It *has* to be executed, but you have
a choice when and where to do it. That's what Souders is good at.

> YAGNI YAGNI YAGNI!

That should be part of the build process.

>> He's also the author of YSlow, which Jeremy mentioned before.
>
> Right. And now he works at Google and they have Page Speed, which I have
> just installed.

Haven't tried Page Speed yet, maybe next month.


- Conrad

Garrett Smith

unread,
Jun 27, 2009, 4:01:07 AM6/27/09
to
Jorge wrote:
> On Jun 26, 9:24 am, neilc <capho...@gmail.com> wrote:
>> (...)
>> There is a discussion here
>>
>> http://stackoverflow.com/questions/21294/how-do-you-dynamically-load-...
>> andhttp://www.artzstudio.com/2008/07/beating-blocking-javascript-asynchr...
>
> And a video here: Steve Souders: "Life's Too Short - Write Fast Code
> (part 2)", "Advanced script loading: six ways to load scripts without
> blocking the page" (starting @10m40s)
> http://www.youtube.com/watch?v=52gL93S3usU
>
> DON'T MISS IT: John Resig's �ber-cool "degrading script pattern",
> starting @22m15s.
>

Thanks for that link. That is horrible advice and should be avoided.

It was discussed on John Resig's website[0].

> I wonder why jewels like these don't make its way into the resources
> FAQ.
>

Good point. It is worth mentioning that there is a lot of poor advice
provided by experts that should not be followed. The web is horribly
broken. This video serves as an excellent example of an "industry
expert" providing up horrible advice. It should be recommended against
and the section on "John Resig's degrading script tags", which Steve
calls "really really awesome", serves as a fine example of why.

<FAQENTRY>
Q: I saw a video online. Why wasn't it in the FAQ?
A: Video presentations often contain advice that is either
incorrect or inadvisable. It possible, though unlikely, that the video
has not been reviewed and contains accurate and valuable information.
Before posting a request for review, please search the archives for
discussion about the video.
</FAQENTRY>

Steve:
| It turns out, this is really really awesome, but it actually doesn't
| work in any browser. There's no browser that works this way to like
| pay attention to the code in the script blocks if there's a source
| attribute being used.
|
| But it turns out its really easy across all browsers to add that.
| And the way we add that is.. Oh, and this is nice because it's
| cleaner, there's only one script tag instead of two script blocks,
| it's clearer, its very clear that this script code has a dependency
| on menu.js, um, and it's safer. If the external script fails, then,
| ah, the inline code won't be scalled.
|
| But, since it doesn't work in any browser, you have to do a little
| work. And it's not that much work and it's not that complicated, so
| at the end of menu.js, so that's why I renamed it to
| "menu-degrading.js", so at the end of "menu-degrading.js", I basically
| just do this loop:
|
| I get all the script elements, I loop through them, until I find the
| script whose name is "menu jay", "menu-degrading.js" and then I look
| at its innerHMTL property. And that's basically going to be, innerHTML
| is going to be this code, right here (points to example), and I just
| eval it.

None of the three reasons is true. All are blatantly false and in being
false, they serve as reasons for eschewing this technique.

Because a SCRIPT element is not allowed to have HTML, expecting a script
tag to have its text available as innerHTML seems risky. For example:

javascript: alert( document.createElement("script").canHaveHTML)

The "inline code" here is defined as fallback content in HTML 4.01[1].
That means it is only displayed if the script does *not* load. That is
the exact opposite of what this technique requires. Here, Steve is
expecting the fallback content of a script tag to be executed only when
the src is loaded. This works exactly the opposite of the way the HTML
4.01 standard states and this was clearly pointed out on John Resig's
blog[3][4]. It is unreasonable for Steve to have ignored this criticism,
yet he continued to advocate it *after* that fact was pointed out. Steve
Souders is arrogant and not amenable to criticism.

The script's innerHTML is then passed to eval.

The file name changed it's not "menu.js", but now "menu-degrading.js",
but notice how Steve gets that wrong a couple of times. That right there
is evidence that the "degrading" part is unrelated to the original code.

The inline code at the end of menu-degrading.js loops through elements
in the document. It uses all global variables, including a global loop
counter |i|. The eval method is called in global context.

Looping through the DOM while the page loads is a strategy that hurts
performance.

AISB, eval is called in global context. Steve did not mention this, and
the code is so naive that I doubt he is even aware of it, but the code
must exist in global context, or use a separate sandbox function. This
has to do with eval using the scope of the calling context, variable
object, and the this value. If eval is called within a function, then it
will use that function's [[Scope]], variable object, and |this| value.
This can complicate the situation by identifiers being resolved to that
scope chain.

Example:
function doEval(s) {
var i = 10;
eval(s);
alert(i);
}

doEval("i = 20;");

Result:
elerts "20";

I've used the identifier |i| on purpose because it is a common mistake
to forget |var| in initializing a loop variable.

Such issue might not happen on a simple first test. However, if put into
production, it could happen at a later time with different data and
different identifiers. It could potentially causing bugs that might not
arise immediately. If and when they happen in production, it would
severly compromise the security of an application. Inline code often
makes use variables from the server, e.g.:- <%= serverOutput %>, so it
might be a problem that could go unnoticed until, well, it became a
horrible security problem.

Steve mentions in that video that "Doug" remained silent when he
mentioned eval.

Another problem with eval is that when an EvalError occurs, the browser
may not provide information about what was being eval'd that caused the
problem. Instead, the browser will state that eval(s) caused a problem.
Since eval can't be stepped into, it is harder to debug. Indeed, this
is a problem in Dojo that I noticed way back in Dojo 0.4.

Back to Steve's example, that the file "menuteir.js" now has to know
something about the application's performance tricks. That is awful
design and a flagrant violation of SRP. Steve says it is cleaner and
clearer. That is untrue. It is less clear, more complicated because it
requires more code inside menuteir.js to execute the inline script
content. The menuteir.js should not be have knowledge of the performance
tricks used to include it. It severely complicates things; it does not
make things simpler, nor clearer.

It does not make things "safer" either, as I have already explained the
problems with eval.

| If the external script fails, then the inline code won't be called.

That may be true in buggy implementations, but according to the HTML
4.01 specification, the exact opposite is designed to happen. Code
should not rely on specification violations. Utilizing proprietary
(MSIE) extensions is one thing, but expecting every browser to go
against the spec is a very *unsafe* design decision.

Not cleaner, nor clearer, nor safer.

The technique requires implementations to violate the HTML 4 standard.
(According to Steve, this is "all browsers"). It complicates the design
of the code, making it harder to tune and increase likelihood of errors.
For browsers that behave the way Steve wants, Steve's approach impacts
performance by looping through the DOM, and, by using eval, introduces
fragility into the code by eval.

It is really a very poor idea. As Randy said, KISS.

Steve Souders is ignoring valid criticism, disregarding public
standards, and throwing caution to the wind.

I see that Randy and Thomas have their own thoughts on this. The
criticism I provide can tends to annoy the "experts" quite a bit. See
the whatwg list for details. Good to see that I am not alone here.

The part about "depends" in 28:00 is where steve talks about declarative
chaining of script loads. It is another very poor design idea, and it
prompted my proposal for "depends" on script tags on whatwg. That design
idea follows the "I'm Done" paradigm, not "Do This". For more
information on "I'm Done", see H.S. Lahman's explanations on comp.object.

The "Managed XHR" solution also requires eval, and has all the
complications associated with that, just as in Dojo.

Technique 4 Script onload aka "The Best One", shows code that modifies
Host objects with expandos. For reasons that have been discussed here
many times, code which modifies host objects is error prone. According
to Steve, if you use both onload and onreadystatechange, it will work in
"all browsers". Again, this relies on the approach of "Do This" instead
of "I'm Done".

I do agree that this deserves mention in the FAQ. If Steve's book is
going to be included, it ought to mention that his application design
advice is considerably harmful.

Garrett
[0]http://ejohn.org/blog/degrading-script-tags#postcomment
[1]http://www.w3.org/TR/html401/interact/scripts.html#h-18.2.1
[3]http://ejohn.org/blog/degrading-script-tags#comment-319983
[4]http://ejohn.org/blog/degrading-script-tags#comment-320005

Gregor Kofler

unread,
Jun 27, 2009, 4:42:23 AM6/27/09
to
One Dumm Hikk meinte:

> Ever wonder why people think JS is so hard? Because they try to
> make it harder than it has to be. KISS - Keep It Simple Stupid.

But then John Resig and his colleagues couldn't fill their blogs with
sparkling new ideas of how to "optimize" code.

As Jorge already mentioned:
http://www.youtube.com/watch?v=52gL93S3usU and the "degrading script
pattern" - it escapes me where the actual problem is, requesting such a
bizarre "solution".

Gregor


--
http://www.gregorkofler.com
http://web.gregorkofler.com - vxJS, a JS lib in progress

Jorge

unread,
Jun 27, 2009, 8:57:00 AM6/27/09
to
Come and see it by yourself:

Parallel script loading SEVERELY cuts scripts loading time:

http://jorgechamorro.com/cljs/068/

--
Jorge.

Jorge

unread,
Jun 27, 2009, 9:39:48 AM6/27/09
to
On Jun 27, 10:42 am, Gregor Kofler <use...@gregorkofler.com> wrote:
> (...)
> As Jorge already mentioned:http://www.youtube.com/watch?v=52gL93S3usUand the "degrading script

> pattern" - it escapes me where the actual problem is, requesting such a
> bizarre "solution".

The problem is:

- Given a script that has not been loaded yet (still loading), -
usually a dynamically inserted one-,
- Find the best way to have some piece of code run asap, immediatly
after the script (above) has loaded and executed.

(note that "onload" is not -usually- available on <script> tags in
most browsers)

I think that Resig's idea is great for many reasons. Unless, or until,
somebody else shows me a better way...

--
Jorge.

Jorge

unread,
Jun 27, 2009, 9:48:00 AM6/27/09
to
On Jun 27, 10:01 am, Garrett Smith <dhtmlkitc...@gmail.com> wrote:
> (...)

> I do agree that this deserves mention in the FAQ. If Steve's book is
> going to be included, it ought to mention that his application design
> advice is considerably harmful.

Mention that *you* consider it harmful.

--
Jorge.

Jorge

unread,
Jun 27, 2009, 10:30:08 AM6/27/09
to
On Jun 27, 3:49 am, One Dumm Hikk <hikksnotath...@aol.com> wrote:
>
> Dynamically loading script files to speed up the loading process?
> Garbage.
>
> What it will do, if done properly, is speed up the initial
> rendering of the page. But it WON'T speed up load time of the
> files and will actually slow it down. The reason it will
> actually slow it down is because it has to do more work to
> load the files. Whether the file is static coded or dynamically
> loaded, the file still has to be downloaded from the server.
> Want it to download faster? Make the file physically smaller.
> Any other advice is magical hocus-pocus for making it load
> faster if everything else is the same.
> (...)


I'm not sure why do you say so, as it's obvious (isn't it ?) that
latency times add up when the scripts are loaded in series.

And for servers that throttle downloads (more and more each day, e.g.
youtube, me.com...), the time to download n scripts in parallel is not
necessarily === n* the time to download a single one.

--
Jorge.

Jorge

unread,
Jun 27, 2009, 11:48:32 AM6/27/09
to

Plus a link to the convoluted non-arguments(*) in your (OMG) long
post...

(*)
1.- WTHIT ?
javascript:alert(document.createElement
("script").canHaveHTML):undefined

2.- Wow:


"The file name changed it's not "menu.js", but now "menu-
degrading.js",
but notice how Steve gets that wrong a couple of times. That right
there
is evidence that the "degrading" part is unrelated to the original
code."

3.- That says nothing about the validity of the pattern:


"The inline code at the end of menu-degrading.js loops through
elements
in the document. It uses all global variables, including a global
loop
counter |i|."

4.- The same global context in which any program (read: <script>) is
run:


"The eval method is called in global context."

5.- idiocy++ ?:


"Looping through the DOM while the page loads is a strategy that
hurts
performance."

6.- Again ?


"AISB, eval is called in global context. Steve did not mention this,
and
the code is so naive that I doubt he is even aware of it"

7.- Of course, it's a <script>, remember ?


"but the code must exist in global context"

8.- Etc...
--
Jorge.

Garrett Smith

unread,
Jun 27, 2009, 1:23:40 PM6/27/09
to
Jorge wrote:
> On Jun 27, 3:48 pm, Jorge <jo...@jorgechamorro.com> wrote:
>> On Jun 27, 10:01 am, Garrett Smith <dhtmlkitc...@gmail.com> wrote:
>>
>>> (...)
>>> I do agree that this deserves mention in the FAQ. If Steve's book is
>>> going to be included, it ought to mention that his application design
>>> advice is considerably harmful.
>> Mention that *you* consider it harmful.

Any rational person reading that couldn't really disagree that what I
wrote was incorrect based on the fact that it was long. The review was
not nearly as long as the video itself

The video contains so much maladvice that a complete review would be
longer than the video itself.

The arguments were valid, clearly stated, and addressed one of the
video's topics in overview and specifics. Steve's advice on application
design and architecture is dangerous and should be eschewed.

>
> Plus a link to the convoluted non-arguments(*) in your (OMG) long
> post...

It was long, I should have trimmed it up a bit. But it was not nearly as
long as the video, right?

That video is potentially harmful. Someone might watch that and
actually believe it was useful.

>
> (*)
> 1.- WTHIT ?

I take it that means "what the hell is this". It is an MSIE property.
I should have mentioned that |canHaveHTML| is an MSIE property[5].

(BTW - the MSDN doc came up #1 in google rank for "canHaveHTML".)

> javascript:alert(document.createElement
> ("script").canHaveHTML):undefined
>


> 2.- Wow:
> "The file name changed it's not "menu.js", but now "menu-
> degrading.js",
> but notice how Steve gets that wrong a couple of times. That right
> there
> is evidence that the "degrading" part is unrelated to the original
> code."
>

The confusion it causes should not be surprising; rather, it is
indicative that the technique is confusing.

> 3.- That says nothing about the validity of the pattern:
> "The inline code at the end of menu-degrading.js loops through
> elements
> in the document. It uses all global variables, including a global
> loop
> counter |i|."
>

Steve says the technique is "safer". It is less safe because of the use
of eval. That point should have been clear. It is also unsafe because,
AISB, it is based on the expectation that all browsers violate HTML 4.01
to make it work.

Garrett
[5]http://msdn.microsoft.com/en-us/library/ms533547(VS.85).aspx

Jorge

unread,
Jun 27, 2009, 3:42:13 PM6/27/09
to
Garrett Smith wrote:
> Jorge wrote:
> (...)

>> 1.- WTHIT ?
>
> I take it that means "what the hell is this". It is an MSIE property.
> I should have mentioned that |canHaveHTML| is an MSIE property[5].
> (...)

> AISB, it is based on the expectation that all browsers violate HTML 4.01
> to make it work.
> (...)

True, <script>s can (and should) not contain *markup* and nobody is
asking for it. In the absence of (inner) markup, .innerHTML becomes ===
.innerText === .textContent === .text. If it makes you feel any better
use the latter. Although -I can only guess- they must have chosen
.innerHTML for a reason.

see:
http://jorgechamorro.com/cljs/070/

--
Jorge.

Jorge

unread,
Jun 27, 2009, 6:07:09 PM6/27/09
to
On Jun 27, 7:23 pm, Garrett Smith <dhtmlkitc...@gmail.com> wrote:
> (...)
> Steve says the technique is "safer". It is less safe because of the use
> of eval. That point should have been clear.(...)

BTW, could you explain to me why/how is it any unsafer eval
(script.text) than a <script> tag ?

TIA,
--
Jorge.

Garrett Smith

unread,
Jun 27, 2009, 6:41:11 PM6/27/09
to

Script content is CDATA[1]. That means it must *not* contain markup.
While that is true, it is not the incompliance that I mention.

What I am talking about is the HTML 4.01 requires the browser to ignore
the element's contents when the script has a URI. See HTML 4.01, 18.2.1
The SCRIPT element:

| If the src attribute is not set, user agents must interpret the
| contents of the element as the script. If the src has a URI value,
| user agents must ignore the element's contents and retrieve the script
| via the URI.

"*must* *ignore*"

And 6.14 Script data:

| User agents must not evaluate script data as HTML markup but instead
| must pass it on as data to a script engine.

And section 6.2 SGML basic types:
| ...
| Although the STYLE and SCRIPT elements use CDATA for their data model,
| for these elements, CDATA must be handled differently by user agents.
| Markup and entities must be treated as raw text and passed to the
| application as is.

Now, in a browser that does not support the script element, it should,
(or must, in other specifications) attempt to process the element's
content.

HTML 4.01, B.1 Notes on invalid documents:
| # If a user agent encounters an element it does not recognize, it
| should try to render the element's content.

XHTML 1, 3.2. User Agent Conformance:
| # If a user agent encounters an element it does not recognize, it must
| process the element's content.

The choice of judgment to use |script.innerHTML| is based on the
expectation that the script will have an innerHTML property containing
the script data as text, that gets passed as-is to eval. That
expectation is, according to Steve Souders, based upon what "all
browsers" do.

Garrett

Garrett Smith

unread,
Jun 28, 2009, 1:20:14 AM6/28/09
to

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

When eval is called, and the code inside eval is parsed, assignment to
identifiers inside that eval'd code resolve to the calling context's
variable object when it is invoked.

Using a SCRIPT tag, that behavior does not happen.

Garrett

David Mark

unread,
Jun 28, 2009, 1:24:54 AM6/28/09
to
On Jun 25, 3:30 pm, Conrad Lender <crlen...@yahoo.com> wrote:
> On 25/06/09 21:00, Peter Michaux wrote:
>
> > On Jun 25, 11:46 am, Jeremy J Starcher <r3...@yahoo.com> wrote:
> >> Load four scripts, they load one after another while blocking all other
> >> elements on the page from loading at the same time.  By making them
> >> dynamically declared script elements (either using document.write or
> >> dynamic SCRIPT elements), it allows concurrent loading with other
> >> elements.
>
> > I wish Randy Webb was around right now. I've cc'ed him on this
> > message. He is/was a fan of dynamic script tag insertion at least for
> > some purposes.
>
> I suppose that was tongue in cheek, but there are in fact techniques

No, dynamic script injection is a practical concern. Randy spent
years researching it (for whatever reason.)

> which can help improve the time it takes to load and render a
> script-heavy page. Steve Souders specializes in this area, and his books
> about high performance web sites are definitely worth a read.

Why do I doubt that?

> His second
> book has only just been released, and I haven't read it yet, but he has
> been very generous about publishing pre-release chapters on his blog.
>
> http://www.stevesouders.com/
>
> David Mark will probably kill me right about now, because Steve Souders
> works at Google, and nothing good has ever come from that company,

Well, Google has never published a single competent line of Javascript
(or Website AFAICT.) You make the call.

> according to David. Nevertheless, IMO there's a lot of interesting

And loads of others.

> information in Souders's books and on his blog; a good starting point
> would be
>
> http://www.stevesouders.com/blog/2009/04/23/even-faster-web-sites/
>
> You don't have to embrace any of the "script injection" techniques he

Lots of empirical data and discussion of techniques, but no script.

> offers, make your own judgement instead. The analysis about where to put
> <style>, <script>, <link> tags, and when different browsers will block
> when they encounter such an element is interesting enough by itself.

Much better to know what you are doing (e.g. limit the number of
external scripts and put them where they need to be, not where you
think they will load "faster.") And for crying out loud, don't inject
anything into the DOM during loading. Sure as hell not in elements
that haven't finished parsing (that's what is biting the OP.)

>
> He's also the author of YSlow, which Jeremy mentioned before.

Of course, an automatic generator of generalized advice (e.g. put
script elements at the bottom of the body.) Again, know what you are
doing and you won't need to consult mechanical Turks.

kangax

unread,
Jun 28, 2009, 3:02:00 AM6/28/09
to
David Mark wrote:
> On Jun 25, 3:30 pm, Conrad Lender <crlen...@yahoo.com> wrote:
[...]

>> David Mark will probably kill me right about now, because Steve Souders
>> works at Google, and nothing good has ever come from that company,
>
> Well, Google has never published a single competent line of Javascript
> (or Website AFAICT.) You make the call.

You are probably talking about browser scripting.

There's a Caja project that Google is working on - a secure subset of
ES3 implemented in ES3 itself. Some of the code in it is state of the
art and is very far from being incompetent. If you look at one of the
Caja's base scripts - cajita.js
<http://code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/cajita.js>,
you will quickly realize that implementing such environment requires a
truly deep understanding of ECMAScript internals. Reading that file
alone is quite enlightening. Speaking of ECMAScript internals, one of
the Caja members - Mark Miller - is also one of ES committee members and
played quite a big role in developing (currently draft) ES5.

Google might not be competent in client-side scripting, but I can't say
the same about their ES-as-a-language skills.

[...]

--
kangax

kangax

unread,
Jun 28, 2009, 3:23:15 AM6/28/09
to
Garrett Smith wrote:
> Jorge wrote:
>> On Jun 27, 7:23 pm, Garrett Smith <dhtmlkitc...@gmail.com> wrote:
>>> (...)
>>> Steve says the technique is "safer". It is less safe because of the use
>>> of eval. That point should have been clear.(...)
>>
>> BTW, could you explain to me why/how is it any unsafer eval
>> (script.text) than a <script> tag ?
>>
>
> The eval function uses the calling context's [[Scope]], Variable object,
> and |this| value.
>
> When eval is called, and the code inside eval is parsed, assignment to
> identifiers inside that eval'd code resolve to the calling context's
> variable object when it is invoked.

I know that ES3 allows for implementations to throw EvalError with
indirect eval calls, but don't browsers instead evaluate in a global scope?

(this happens in at least FF 3 and Safari 4)

var x = 'outer';
(function(){
var x = 'inner';
return this.eval('x');
})();


[...]

--
kangax

Jorge

unread,
Jun 28, 2009, 3:37:47 AM6/28/09
to

Thanks, but AFAICS, an eval('code') at the top level is ===
<script>'code'</script> :

- 'this' === window,
- [[scope]] === global context, and
- no Variable 'object'.

--
Jorge.

Jorge

unread,
Jun 28, 2009, 3:52:32 AM6/28/09
to

var x = 'outer';
(function f () {
var x = 'inner';
alert(window.eval('x'));
})();

--> outer

var x = 'outer';
(function f () {
var x = 'inner';
alert(eval('x'));
})();

--> inner

--
Jorge.

David Mark

unread,
Jun 28, 2009, 3:56:26 AM6/28/09
to
On Jun 28, 3:02 am, kangax <kan...@gmail.com> wrote:
> David Mark wrote:
> > On Jun 25, 3:30 pm, Conrad Lender <crlen...@yahoo.com> wrote:
> [...]
> >> David Mark will probably kill me right about now, because Steve Souders
> >> works at Google, and nothing good has ever come from that company,
>
> > Well, Google has never published a single competent line of Javascript
> > (or Website AFAICT.)  You make the call.
>
> You are probably talking about browser scripting.

Of course.

>
> There's a Caja project that Google is working on - a secure subset of
> ES3 implemented in ES3 itself. Some of the code in it is state of the
> art and is very far from being incompetent. If you look at one of the
> Caja's base scripts - cajita.js

> <http://code.google.com/p/google-caja/source/browse/trunk/src/com/goog...>,


> you will quickly realize that implementing such environment requires a
> truly deep understanding of ECMAScript internals.

// Copyright (C) 2007 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* @fileoverview the Cajita runtime library.
* It is written in Javascript, not Cajita, and would be rejected by
the Cajita
* translator. This module exports two globals:<ol>
* <li>"___" for use by the output of the Cajita translator and by
some
* other untranslated Javascript code.
* <li>"cajita" providing some common services to the Cajita
programmer.
* </ol>
* @author eri...@gmail.com
* @requires console
* @provides ___, arraySlice, cajita, dateToISOString, funcBind
* @overrides Array, Boolean, Date, Function, Number, Object, RegExp,
String
* @overrides Error, EvalError, RangeError, ReferenceError,
SyntaxError,
* TypeError, URIError
*/

// TODO(erights): All code text in comments should be enclosed in
// {@code ...}.

// TODO(ihab.awad): Missing tests in CajitaTest.java for the
functionality
// in this file.

I guess this is unfinished. (?)


// Add a tag to whitelisted builtin constructors so we can check the
class
// cross-frame. Note that Function is not on the list.

Array.typeTag___ = 'Array';
Object.typeTag___ = 'Object';
String.typeTag___ = 'String';
Boolean.typeTag___ = 'Boolean';
Number.typeTag___ = 'Number';
Date.typeTag___ = 'Date';
RegExp.typeTag___ = 'RegExp';
Error.typeTag___ = 'Error';
EvalError.typeTag___ = 'EvalError';
RangeError.typeTag___ = 'RangeError';
ReferenceError.typeTag___ = 'ReferenceError';
SyntaxError.typeTag___ = 'SyntaxError';
TypeError.typeTag___ = 'TypeError';
URIError.typeTag___ = 'URIError';

Whatever this is setting up, I'm sure I won't like it. I stopped
reading at this point.

> Reading that file
> alone is quite enlightening.

Not as far as I got.

> Speaking of ECMAScript internals, one of
> the Caja members - Mark Miller - is also one of ES committee members and

Of the "Miller Device", which turned out to be incompatible with IE?
And "ES committee member" is no badge of honor (isn't Resig on that
list?)

>   played quite a big role in developing (currently draft) ES5.

He's doing a hell of job from what I've heard. :(

>
> Google might not be competent in client-side scripting, but I can't say
> the same about their ES-as-a-language skills.

That's as maybe. But why don't they get some of these ES luminaries
to rewrite their grade Z browser scripts? Aren't they in the business
of publishing Websites?

David Mark

unread,
Jun 28, 2009, 4:05:20 AM6/28/09
to
On Jun 28, 3:23 am, kangax <kan...@gmail.com> wrote:
> Garrett Smith wrote:
> > Jorge wrote:
> >> On Jun 27, 7:23 pm, Garrett Smith <dhtmlkitc...@gmail.com> wrote:
> >>> (...)
> >>> Steve says the technique is "safer". It is less safe because of the use
> >>> of eval. That point should have been clear.(...)
>
> >> BTW, could you explain to me why/how is it any unsafer eval
> >> (script.text) than a <script> tag ?
>
> > The eval function uses the calling context's [[Scope]], Variable object,
> > and |this| value.
>
> > When eval is called, and the code inside eval is parsed, assignment to
> > identifiers inside that eval'd code resolve to the calling context's
> > variable object when it is invoked.
>
> I know that ES3 allows for implementations to throw EvalError with
> indirect eval calls, but don't browsers instead evaluate in a global scope?

Some might if the Global Object is used. Don't count on it though
(better strategy is to count on an exception.)

>
> (this happens in at least FF 3 and Safari 4)

I wouldn't infer anything from that.

>
> var x = 'outer';

AIUI, this would be more future-proof with regard to the next version
of ES:

var GLOBAL = this;

> (function(){
>    var x = 'inner';
>    return this.eval('x');

return GLOBAL.eval('x');

>
> })();
>

But best to avoid it entirely.

David Mark

unread,
Jun 28, 2009, 4:10:26 AM6/28/09
to

Bad assumption, but irrelevant here.

> - [[scope]] === global context, and

Not exactly.

And are you planning to run this XHR/eval combo in the global
context? I would expect it to reside in a function.

> - no Variable 'object'.

See above.

David Mark

unread,
Jun 28, 2009, 4:11:52 AM6/28/09
to

There's no guarantee that this method will exist on the window object,
which is not necessarily the Global Object anyway.

>
> })();
>
> --> outer
>
> var x = 'outer';
> (function f () {
>    var x = 'inner';
>    alert(eval('x'));
>
> })();
>
> --> inner

Proves absolutely nothing.

Richard Cornford

unread,
Jun 28, 2009, 9:05:25 AM6/28/09
to
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?

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.

Consider this scenario; The browser is going to follow the HTTP
restrictions and limit the number of simultaneous HTTP connections to 2,
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
sheet, there is no reason in the world why it should do anything to
interrupt that process.

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

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

> I forget how they tested the other browsers.

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.

Richard.

Richard Cornford

unread,
Jun 28, 2009, 9:05:27 AM6/28/09
to

Once again, you show the experiment but not the reasoning that gets you
from the results of that experiment to your (very general) conclusion.

There is also some significant information missing, such as how many
simultaneous HTTP connections the server delivering the JS files is
configured to allow. Because while the HTTP spec states that only 2
simultaneous connections should be made to a server (RFC 2616, Section
8.1.4, Paragraph 6) some user agents have been observed to make
considerably more (10 to 20 in extreams).

The problem with deducing your general conclusion that "Parallel script
loading SEVERELY cuts scripts loading time" from your experiment is that
your experiment takes place after the page has loaded; at a time when
parsing and (progressive) rendering are not active and when there is no
ongoing demand to be downloading resources (when no HTTP connections are
being called upon to do other things).

All that actually is shown by the experiment is that if you only use one
HTTP connection (download resources serially) the process takes longer
than if you use more than one connection at the same time. Hardly
surprising as if the number of connections made did not influence
download performance then there would be no reason for ever making more
than one connection to a server at a time.

Richard.

Richard Cornford

unread,
Jun 28, 2009, 9:31:00 AM6/28/09
to
kangax wrote:
<snip>

> I know that ES3 allows for implementations to throw EvalError
> with indirect eval calls, but don't browsers instead evaluate
> in a global scope?
<snip>
> return this.eval('x');
<snip>

Some have been observed to. It is worth saying more about what is meant
by an "indirect" call to eval.

var e = eval;
e(sCode);

- is an indirect call to eval. While - this.eval(sCode); - is also an
indirect call to eval it is also a call to an - eval - method of an
object (the global object). Early JavaScript(tm) implementations had
an - eval - method on every object (and some JavaScript(tm) imitators
copied that). Those methods were deprecated some time back, and appear
to have vanished from the latest JavaScript(tm) versions, but their
behaviour was to allow the setting up of the - this - value to the
object on which the method was called. I don't recall what the - eval -
methods did about adopting scope chains. Obviously as a non-standard
language extensions _and_ and eval method, the method was little more
than a curiosity.

The trend to have unexpected forms of eval call execute their programs
in a global execution context seems to me to be a recent phenomenon that
is a response to a demand from people who want to be able to load
javascript code as string data but cannot cope with the consequences of
having to have it executed in a function's execution context. The trend
does not surprise me, but I am less than sympathetic towards those who
have burdened themselves with the need for it.

Richard.

Conrad Lender

unread,
Jun 28, 2009, 5:45:13 PM6/28/09
to
On 27/06/09 10:01, Garrett Smith wrote:
> <FAQENTRY>
> Q: I saw a video online. Why wasn't it in the FAQ?
> A: Video presentations often contain advice that is either
> incorrect or inadvisable. It possible, though unlikely, that the video
> has not been reviewed and contains accurate and valuable information.
> Before posting a request for review, please search the archives for
> discussion about the video.
> </FAQENTRY>

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.

> Steve:
...


> | I get all the script elements, I loop through them, until I find the
> | script whose name is "menu jay", "menu-degrading.js" and then I look
> | at its innerHMTL property.

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.

> None of the three reasons is true. All are blatantly false and in being
> false, they serve as reasons for eschewing this technique.

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.

> AISB, eval is called in global context. Steve did not mention this, and
> the code is so naive that I doubt he is even aware of it, but the code
> must exist in global context, or use a separate sandbox 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:

function evil (code) {
return eval(code);
}

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

> Another problem with eval is that when an EvalError occurs, the browser
> may not provide information about what was being eval'd that caused the
> problem. Instead, the browser will state that eval(s) caused a problem.
> Since eval can't be stepped into, it is harder to debug.

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 is less clear, more complicated because it
> requires more code inside menuteir.js to execute the inline script
> content. The menuteir.js should not be have knowledge of the performance
> tricks used to include it. It severely complicates things; it does not
> make things simpler, nor clearer.

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

> The "Managed XHR" solution also requires eval, and has all the
> complications associated with that, just as in Dojo.

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.

> Technique 4 Script onload aka "The Best One", shows code that modifies
> Host objects with expandos. For reasons that have been discussed here
> many times, code which modifies host objects is error prone.

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.

> I do agree that this deserves mention in the FAQ. If Steve's book is
> going to be included, it ought to mention that his application design
> advice is considerably harmful.

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?


- Conrad

David Mark

unread,
Jun 28, 2009, 6:44:29 PM6/28/09
to

No way his book is going in the FAQ, unless it is specifically
recommended against.

This is another one of these guys who think programming is making
videos of themselves, using the word "awesome" a lot, congratulating
fellow ignoramuses on their videos, etc. He very obviously knows
nothing about browser scripting or sound Web development techniques
(echoing the familiar Web2.0 follies of the last four years or so.)
These hucksters are part of the past; never mind if their programs are
still in syndication (so is Gilligan's Island.)

One Dumm Hikk

unread,
Jun 28, 2009, 8:39:35 PM6/28/09
to
On Jun 27, 9:39 am, Jorge <jo...@jorgechamorro.com> wrote:
> On Jun 27, 10:42 am, Gregor Kofler <use...@gregorkofler.com> wrote:
>
> > (...)
> > As Jorge already mentioned:http://www.youtube.com/watch?v=52gL93S3usUandthe "degrading script

> > pattern" - it escapes me where the actual problem is, requesting such a
> > bizarre "solution".
>
> The problem is:
>
> - Given a script that has not been loaded yet (still loading), -
> usually a dynamically inserted one-,
> - Find the best way to have some piece of code run asap, immediatly
> after the script (above) has loaded and executed.
>
> (note that "onload" is not -usually- available on <script> tags in
> most browsers)

That is trivial to do. Again, people try to make this stuff
harder than it has to be. Want a fool proof way to make a script
in an external file execute and know that is has loaded? Search
the archives, I have shown this MANY times and it was even before
many people knew JRs name.
At the end of the external file, place the call to the function
that you want executed. It will NOT get executed until the file
is loaded and it will get called only when the file gets loaded.
Stop making this harder than it has to be. Sheesh people.

On Jun 27, 10:30 am, Jorge <jo...@jorgechamorro.com> wrote:
> On Jun 27, 3:49 am, One Dumm Hikk <hikksnotath...@aol.com> wrote:
> > Dynamically loading script files to speed up the loading process?
> > Garbage.
>
> > What it will do, if done properly, is speed up the initial
> > rendering of the page. But it WON'T speed up load time of the
> > files and will actually slow it down. The reason it will
> > actually slow it down is because it has to do more work to
> > load the files. Whether the file is static coded or dynamically
> > loaded, the file still has to be downloaded from the server.
> > Want it to download faster? Make the file physically smaller.
> > Any other advice is magical hocus-pocus for making it load
> > faster if everything else is the same.
> > (...)
>
> I'm not sure why do you say so, as it's obvious (isn't it ?) that
> latency times add up when the scripts are loaded in series.

I say that because its patently true. Unless you want to try to
convince me that connection speed is determined by how the file
was attempted to be loaded. Again, take a HARD look at the original
script, how it was written, and how it would work. Then let's
discuss what it will or won't do.

> And for servers that throttle downloads (more and more each day, e.g.
> youtube, me.com...), the time to download n scripts in parallel is not
> necessarily === n* the time to download a single one.

How a file is called is irrelevant to the amount of time it takes to
download that file. IE is notorious for loading multiple files at once
irregardless of how you try to load it.

For a file that is of size S, it will take a given amount of time T,
to
download the file from the server *irregardless of how its requested*
if
all other parameters are equal. Same network speed, same processes on
the
computer making the request, same server load.

The difference it makes is the appearance of loading faster by
rendering
the HTML aspects of the page first.

Has John Resig gotten any clue about JS in the last 18 months or so?
If he hasn't, then he still doesn't have a clue.

One Dumm Hikk

unread,
Jun 28, 2009, 8:48:46 PM6/28/09
to
On Jun 28, 1:24 am, David Mark <dmark.cins...@gmail.com> wrote:
> On Jun 25, 3:30 pm, Conrad Lender <crlen...@yahoo.com> wrote:
>
> > On 25/06/09 21:00, Peter Michaux wrote:
>
> > > On Jun 25, 11:46 am, Jeremy J Starcher <r3...@yahoo.com> wrote:
> > >> Load four scripts, they load one after another while blocking all other
> > >> elements on the page from loading at the same time.  By making them
> > >> dynamically declared script elements (either using document.write or
> > >> dynamic SCRIPT elements), it allows concurrent loading with other
> > >> elements.
>
> > > I wish Randy Webb was around right now. I've cc'ed him on this
> > > message. He is/was a fan of dynamic script tag insertion at least for
> > > some purposes.
>
> > I suppose that was tongue in cheek, but there are in fact techniques
>
> No, dynamic script injection is a practical concern.  Randy spent
> years researching it (for whatever reason.)

It started out a personal project that turned into a professional
project.
When properly done dynamic script insertion is a ton faster than
traditional methods. The problem is not many people know how to do it
properly so that it is in fact faster. 99% of the sites I look at that
use dynamic content retrieval do it wrong.

I have always said that unless the back end is written to support the
front end then dynamic insertion is a waste of time and causes more
problems than it solves. There is even a post in the thread about
how to handle eval'ed code. If the back end had been written properly
for the retrieval method, that wouldn't be an issue.

What people are looking for is a band aid to speed up a poorly written
bloated page that if re-written with speed in mind, wouldn't need the
band-aid to start with.

This isn't intended for you personally David, so don't take it that
way, you just happened to be the one I replied to :)

Has John Resig learned any Javascript in the last 2 years or so? I
know he didn't know any then (other than enough to be disastrously
dangerous).

Jorge

unread,
Jun 28, 2009, 8:49:47 PM6/28/09
to
On Jun 28, 3:05 pm, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:

> Jorge wrote:
> > Come and see it by yourself:
>
> > Parallel script loading SEVERELY cuts scripts loading time:
>
> >http://jorgechamorro.com/cljs/068/
>
> Once again, you show the experiment but not the reasoning that gets you
> from the results of that experiment to your (very general) conclusion.
>
> There is also some significant information missing, such as how many
> simultaneous HTTP connections the server delivering the JS files is
> configured to allow. Because while the HTTP spec states that only 2
> simultaneous connections should be made to a server (RFC 2616, Section
> 8.1.4, Paragraph 6) some user agents have been observed to make
> considerably more (10 to 20 in extreams).

In this regard the limiting factor seems to be in the browsers
themselves not in me.com.

> The problem with deducing your general conclusion that "Parallel script
> loading SEVERELY cuts scripts loading time" from your experiment is that
> your experiment takes place after the page has loaded; at a time when
> parsing and (progressive) rendering are not active and when there is no
> ongoing demand to be downloading resources (when no HTTP connections are
> being called upon to do other things).

Yes, and ... ? Of course when/if there aren't for any reason any more
available download "slots" downloading can't/won't take place in
parallel.

> All that actually is shown by the experiment is that if you only use one
> HTTP connection (download resources serially) the process takes longer
> than if you use more than one connection at the same time. Hardly
> surprising as if the number of connections made did not influence
> download performance then there would be no reason for ever making more
> than one connection to a server at a time.

Yes and no. The point is that a series of <script> tags hardcoded in
the source .html will be loaded in series while the same <scripts>
inserted dynamically load in parallel.

And then the problem of synchronizing load times and execution times
arises, hence Resig's degrading script tag idea becomes relevant as a
solution to a problem previously inexistent.

See: http://jorgechamorro.com/cljs/071/

It times the loading of 4 scripts:

(1)- dynamically inserting them all at once
(2)- dynamically inserting them in series
(3)- document.writting them all at once
(4)- normally: 4 <script> tags hardcoded in the .html source.

(1) is the fastest in all the current and past browsers. Only the
latest Safari 4, FF3.5 beta and Opera 10 beta manage to speedup (3)
and sometimes (4) as well.

All the action now takes place before onload.

--
Jorge.

kangax

unread,
Jun 28, 2009, 9:03:17 PM6/28/09
to
Richard Cornford wrote:
> kangax wrote:
> <snip>
>> I know that ES3 allows for implementations to throw EvalError
>> with indirect eval calls, but don't browsers instead evaluate
>> in a global scope?
> <snip>
>> return this.eval('x');
> <snip>
>
> Some have been observed to. It is worth saying more about what is meant
> by an "indirect" call to eval.
>
> var e = eval;
> e(sCode);
>
> - is an indirect call to eval. While - this.eval(sCode); - is also an
> indirect call to eval it is also a call to an - eval - method of an
> object (the global object). Early JavaScript(tm) implementations had an
> - eval - method on every object (and some JavaScript(tm) imitators
> copied that). Those methods were deprecated some time back, and appear
> to have vanished from the latest JavaScript(tm) versions, but their
> behaviour was to allow the setting up of the - this - value to the
> object on which the method was called. I don't recall what the - eval -
> methods did about adopting scope chains. Obviously as a non-standard
> language extensions _and_ and eval method, the method was little more
> than a curiosity.

Ah yes of course. Thanks for reminder.

>
> The trend to have unexpected forms of eval call execute their programs
> in a global execution context seems to me to be a recent phenomenon that

I actually haven't noticed "unexpected forms of eval" to be a trend. A
popular way to eval in a global scope seems to be by using script
insertion (e.g. jQuery does that).

Relying on a non-standard behavior of indirect eval doesn't seem like a
robust solution, but then it is often possible to properly feature-test
any non-standard solution before attempting to use it. I just checked
few Mac OSX browsers on how they handle indirect calls.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
with(this) {
var globalEval = function(str) {
return eval(str);
};


}
var x = 'outer';
(function(){

var x = 'inner', evil = eval;
document.write(
'eval: ' +
eval('x') +
'<br>indirect: ' +
(function(){
try { return evil('x'); } catch(e) { return e; }
})() +
'<br>with: ' +
globalEval('x'));
})();
</script>
</body>
</html>

eval | indirect | with |
----------------------------------------------
Firefox 3.0.x inner | outer | outer |

----------------------------------------------
Safari 4 inner | outer | outer |
----------------------------------------------
Safari 3.0.4 inner | inner | outer |
----------------------------------------------
Safari 2.0.4 inner | inner | outer |

----------------------------------------------
Opera 10b inner | outer | outer |
----------------------------------------------
Opera 9.64 inner | outer | outer |
----------------------------------------------
Opera 8.54 inner | EvalError | outer |

----------------------------------------------
Camino 1.6.8 inner | outer | outer |


All quite predictable.


> is a response to a demand from people who want to be able to load
> javascript code as string data but cannot cope with the consequences of
> having to have it executed in a function's execution context. The trend
> does not surprise me, but I am less than sympathetic towards those who
> have burdened themselves with the need for it.

I agree that this is often a non-issue. I can't see the case where
global eval would be useful, but I'm sure there are cases like that.


--
kangax

Jorge

unread,
Jun 28, 2009, 9:57:04 PM6/28/09
to
One Dumm Hikk wrote:
> On Jun 27, 9:39 am, Jorge <jo...@jorgechamorro.com> wrote:
>> On Jun 27, 10:42 am, Gregor Kofler <use...@gregorkofler.com> wrote:
>>
>>> (...)
>>> As Jorge already mentioned:http://www.youtube.com/watch?v=52gL93S3usUandthe "degrading script
>>> pattern" - it escapes me where the actual problem is, requesting such a
>>> bizarre "solution".
>> The problem is:
>>
>> - Given a script that has not been loaded yet (still loading), -
>> usually a dynamically inserted one-,
>> - Find the best way to have some piece of code run asap, immediatly
>> after the script (above) has loaded and executed.
>>
>> (note that "onload" is not -usually- available on <script> tags in
>> most browsers)
>
> That is trivial to do. Again, people try to make this stuff
> harder than it has to be. Want a fool proof way to make a script
> in an external file execute and know that is has loaded? Search
> the archives, I have shown this MANY times and it was even before
> many people knew JRs name.
> At the end of the external file, place the call to the function
> that you want executed.

Yes we do that in e.g. every JSONP response.

> It will NOT get executed until the file
> is loaded and it will get called only when the file gets loaded.
> Stop making this harder than it has to be. Sheesh people.

That f() must be a global and requires a previous, separate <script>.
Resig's solution requires none of these.

> On Jun 27, 10:30 am, Jorge <jo...@jorgechamorro.com> wrote:
>> On Jun 27, 3:49 am, One Dumm Hikk <hikksnotath...@aol.com> wrote:
>>> Dynamically loading script files to speed up the loading process?
>>> Garbage.
>>> What it will do, if done properly, is speed up the initial
>>> rendering of the page. But it WON'T speed up load time of the
>>> files and will actually slow it down. The reason it will
>>> actually slow it down is because it has to do more work to
>>> load the files. Whether the file is static coded or dynamically
>>> loaded, the file still has to be downloaded from the server.
>>> Want it to download faster? Make the file physically smaller.
>>> Any other advice is magical hocus-pocus for making it load
>>> faster if everything else is the same.
>>> (...)
>> I'm not sure why do you say so, as it's obvious (isn't it ?) that
>> latency times add up when the scripts are loaded in series.
>
> I say that because its patently true. Unless you want to try to
> convince me that connection speed is determined by how the file
> was attempted to be loaded. Again, take a HARD look at the original
> script, how it was written, and how it would work. Then let's
> discuss what it will or won't do.

<script>s hardcoded in the source .html halt parsing and download in
series, while dynamically inserted ones don't halt parsing and download
in parallel.

>> And for servers that throttle downloads (more and more each day, e.g.
>> youtube, me.com...), the time to download n scripts in parallel is not
>> necessarily === n* the time to download a single one.
>
> How a file is called is irrelevant to the amount of time it takes to
> download that file.

It isn't, see above.

> IE is notorious for loading multiple files at once
> irregardless of how you try to load it.


> For a file that is of size S, it will take a given amount of time T,
> to
> download the file from the server *irregardless of how its requested*
> if
> all other parameters are equal. Same network speed, same processes on
> the
> computer making the request, same server load.

We're talking about parallel download therefore we're talking of
several, more than one files.

> The difference it makes is the appearance of loading faster by
> rendering
> the HTML aspects of the page first.
>
> Has John Resig gotten any clue about JS in the last 18 months or so?
> If he hasn't, then he still doesn't have a clue.

DM in disguise ?

--
Jorge.

David Mark

unread,
Jun 28, 2009, 10:07:16 PM6/28/09
to
On Jun 28, 9:57 pm, Jorge <jo...@jorgechamorro.com> wrote:
> One Dumm Hikk wrote:
> > On Jun 27, 9:39 am, Jorge <jo...@jorgechamorro.com> wrote:
> >> On Jun 27, 10:42 am, Gregor Kofler <use...@gregorkofler.com> wrote:
>
> >>> (...)
> >>> As Jorge already mentioned:http://www.youtube.com/watch?v=52gL93S3usUandthe"degrading script
> >>> pattern" - it escapes me where the actual problem is, requesting such a
> >>> bizarre "solution".
> >> The problem is:
>
> >> - Given a script that has not been loaded yet (still loading), -
> >> usually a dynamically inserted one-,
> >> - Find the best way to have some piece of code run asap, immediatly
> >> after the script (above) has loaded and executed.
>
> >> (note that "onload" is not -usually- available on <script> tags in
> >> most browsers)
>
> > That is trivial to do. Again, people try to make this stuff
> > harder than it has to be. Want a fool proof way to make a script
> > in an external file execute and know that is has loaded? Search
> > the archives, I have shown this MANY times and it was even before
> > many people knew JRs name.
> > At the end of the external file, place the call to the function
> > that you want executed.
>
> Yes we do that in e.g. every JSONP response.

Good for you.

>
>  > It will NOT get executed until the file
>
> > is loaded and it will get called only when the file gets loaded.
> > Stop making this harder than it has to be. Sheesh people.
>
> That f() must be a global and requires a previous, separate <script>.
> Resig's solution requires none of these.

Resig has no solutions, only snake oil. You are the only one in here
stupid enough to miss that.

>
>
>
> > On Jun 27, 10:30 am, Jorge <jo...@jorgechamorro.com> wrote:
> >> On Jun 27, 3:49 am, One Dumm Hikk <hikksnotath...@aol.com> wrote:
> >>> Dynamically loading script files to speed up the loading process?
> >>> Garbage.
> >>> What it will do, if done properly, is speed up the initial
> >>> rendering of the page. But it WON'T speed up load time of the
> >>> files and will actually slow it down. The reason it will
> >>> actually slow it down is because it has to do more work to
> >>> load the files. Whether the file is static coded or dynamically
> >>> loaded, the file still has to be downloaded from the server.
> >>> Want it to download faster? Make the file physically smaller.
> >>> Any other advice is magical hocus-pocus for making it load
> >>> faster if everything else is the same.
> >>> (...)
> >> I'm not sure why do you say so, as it's obvious (isn't it ?) that
> >> latency times add up when the scripts are loaded in series.
>
> > I say that because its patently true. Unless you want to try to
> > convince me that connection speed is determined by how the file
> > was attempted to be loaded. Again, take a HARD look at the original
> > script, how it was written, and how it would work. Then let's
> > discuss what it will or won't do.
>
> <script>s hardcoded in the source .html halt parsing and download in
> series, while dynamically inserted ones don't halt parsing and download
> in parallel.

Re-read the thread from the beginning.

>
> >> And for servers that throttle downloads (more and more each day, e.g.
> >> youtube, me.com...), the time to download n scripts in parallel is not
> >> necessarily === n* the time to download a single one.
>
> > How a file is called is irrelevant to the amount of time it takes to
> > download that file.
>
> It isn't, see above.

Or just read what you quote.

>
> > IE is notorious for loading multiple files at once
> > irregardless of how you try to load it.
> > For a file that is of size S, it will take a given amount of time T,
> > to
> > download the file from the server *irregardless of how its requested*
> > if
> > all other parameters are equal. Same network speed, same processes on
> > the
> > computer making the request, same server load.
>
> We're talking about parallel download therefore we're talking of
> several, more than one files.

Randy knows what he is talking about. You haven't got the slightest
clue.

>
> > The difference it makes is the appearance of loading faster by
> > rendering
> > the HTML aspects of the page first.
>
> > Has John Resig gotten any clue about JS in the last 18 months or so?
> > If he hasn't, then he still doesn't have a clue.
>
> DM in disguise ?

See what I mean?

David Mark

unread,
Jun 28, 2009, 10:18:34 PM6/28/09
to
On Jun 28, 8:48 pm, One Dumm Hikk <hikksnotath...@aol.com> wrote:
> On Jun 28, 1:24 am, David Mark <dmark.cins...@gmail.com> wrote:
>
>
>
> > On Jun 25, 3:30 pm, Conrad Lender <crlen...@yahoo.com> wrote:
>
> > > On 25/06/09 21:00, Peter Michaux wrote:
>
> > > > On Jun 25, 11:46 am, Jeremy J Starcher <r3...@yahoo.com> wrote:
> > > >> Load four scripts, they load one after another while blocking all other
> > > >> elements on the page from loading at the same time.  By making them
> > > >> dynamically declared script elements (either using document.write or
> > > >> dynamic SCRIPT elements), it allows concurrent loading with other
> > > >> elements.
>
> > > > I wish Randy Webb was around right now. I've cc'ed him on this
> > > > message. He is/was a fan of dynamic script tag insertion at least for
> > > > some purposes.
>
> > > I suppose that was tongue in cheek, but there are in fact techniques
>
> > No, dynamic script injection is a practical concern.  Randy spent
> > years researching it (for whatever reason.)
>
> It started out a personal project that turned into a professional
> project.
> When properly done dynamic script insertion is a ton faster than
> traditional methods. The problem is not many people know how to do it
> properly so that it is in fact faster. 99% of the sites I look at that
> use dynamic content retrieval do it wrong.

I find that applies to virtually every browser scripting task. I'm
sure this one is no exception. Certainly if they use jQuery they are
doing it wrong.

>
> I have always said that unless the back end is written to support the
> front end then dynamic insertion is a waste of time and causes more
> problems than it solves. There is even a post in the thread about
> how to handle eval'ed code. If the back end had been written properly
> for the retrieval method, that wouldn't be an issue.

Right. The two halves can't be developed independently, else you have
to turn to some ridiculous universal solution, which turns out to be
an ugly hack.

>
> What people are looking for is a band aid to speed up a poorly written
> bloated page that if re-written with speed in mind, wouldn't need the
> band-aid to start with.

Exactly.

>
> This isn't intended for you personally David, so don't take it that
> way, you just happened to be the one I replied to :)

I have no doubt this isn't against me. I think everybody knows I
agree with virtually all of it. My addScript method borrows heavily
from your work in this area.

>
> Has John Resig learned any Javascript in the last 2 years or so? I
> know he didn't know any then (other than enough to be disastrously
> dangerous).

Funny you should ask. He (or somebody over there) copied the
addScript method for the latest breakthrough jQuery version (now with
feature testing!) Have a look at it if you want a laugh. In a
nutshell, if IE throws an exception on adding a child to the SCRIPT
element, it is assumed that the text property will work. Something
like that. Got a little lost in translation I guess.

Jorge

unread,
Jun 28, 2009, 10:22:35 PM6/28/09
to
Conrad Lender wrote:
> On 27/06/09 10:01, Garrett Smith wrote:
>> <FAQENTRY>
>> Q: I saw a video online. Why wasn't it in the FAQ?
>> A: Video presentations often contain advice that is either
>> incorrect or inadvisable. It possible, though unlikely, that the video
>> has not been reviewed and contains accurate and valuable information.
>> Before posting a request for review, please search the archives for
>> discussion about the video.
>> </FAQENTRY>
>
> 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.

They've got "their" own FAQ, I've got my own posts... :-)

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

Why ?

>> Steve:
> ....


>> | I get all the script elements, I loop through them, until I find the
>> | script whose name is "menu jay", "menu-degrading.js" and then I look
>> | at its innerHMTL property.
>
> 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.
>
>> None of the three reasons is true. All are blatantly false and in being
>> false, they serve as reasons for eschewing this technique.
>
> JFTR, I don't recommend this technique either. The fact that it's
> invalid HTML

Is it ? Sure ? it's got text content not markup... (?)

> is reason enough for me. (...)

--
Jorge.

Conrad Lender

unread,
Jun 28, 2009, 11:59:04 PM6/28/09
to
On 29/06/09 04:22, Jorge wrote:

> Conrad Lender wrote:
>> 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.
>
> They've got "their" own FAQ, I've got my own posts... :-)

Suit yourself, but it appears that some people are getting annoyed by
your additions.

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

I didn't want to go too far off-topic here, but since you asked...

<OT>
In a nutshell, it has more to do with JSLint and its author than the
book. DC keeps redefining what is or isn't part of the Good Parts, and
immediately updates JSLint to enforce his new insights. That makes the
tool unpredictable and hard to work with. The latest case in this series
was a discussion about whether JSLint should warn about the use of
'continue'. Opinions about its use vary; some consider it bad style,
because it is "a glorified goto". On the other hand, they had nothing
against 'break' and its ability to jump to labels. Somebody even
suggested that 'return' and 'switch' had to trigger warnings, because
they were evil as well. I disagreed, but wrote that an option/flag would
be fine. Nope, DC has put the issue up to a secret vote, and whatever
the result, it won't be implemented as an option. Unfortunately, some of
the most vocal people on the mailing list don't understand much
JavaScript, and are so much in awe of DC that they immediately agree
with everything he says, making the outcome of this vote a forgone
conclusion.

Stuff like that prompted me to write a wrapper script for JSLint, which
recognizes /*markers*/ in lines for which warnings should be suppressed.
Many other lint tools support this in one form or another. I had
suggested such a feature to DC last year, when I found that 'new
Array(10).join("foo")' would trigger unsuppressable warnings, and that
the escaping requirements for regular expressions were way too strict.
Having mentioned these examples, I got the following reply from DC: "I
recommend that you fix your code instead of documenting that it is
intentionally defective." A few months later, the regex problems in
JSLint were silently fixed, and 'new Array(integer)' is now permitted.
I'm getting tired of arguing about anything on that list, and I'm glad
I've still got my wrapper, so I can chose to ignore the more annoying
changes. JSLint is still a very valuable tool, and I would be less
productive without it.
</OT>

>> JFTR, I don't recommend this technique either. The fact that it's
>> invalid HTML
>
> Is it ? Sure ? it's got text content not markup... (?)

You're right, it's not invalid HTML. I still don't think it's a very
good idea. People who read the HTML would naturally assume that the code
wouldn't get executed, unless they know this trick, and know that the
included script makes use of it. Then they would have to know if the
contents are executed "when the page is ready", which is also up to the
included file, and they may or may not be able to use document.write in
this block. There's also the question of what happens when a script on
that page creates more <script> elements. All in all it seems like a lot
of trouble for little effect.


- Conrad

One Dumm Hikk

unread,
Jun 29, 2009, 2:11:35 AM6/29/09
to
On Jun 28, 9:57 pm, Jorge <jo...@jorgechamorro.com> wrote:

Pure nonsense. It doesn't have to be global nor does it
"require a previous, seperate <script>".
f() can be a property of a single global object and the call
can be made in the same file that you are loading. I know that
to be true because its the way I have been doing it for many
years now. Download a .js file that has data in it with a
function call at the end of the file that deals with the
data in the file. That is how you deal with the issue of
knowing when/if the file is downloaded or not. It is
the ONLY *reliable* way to know that the data file has
downloaded.

Perhaps you should search the c.l.j archives for
"dynamic script insertion" and spend the next two
weeks or so reading the many many threads on this
topic.

> > On Jun 27, 10:30 am, Jorge <jo...@jorgechamorro.com> wrote:
> >> On Jun 27, 3:49 am, One Dumm Hikk <hikksnotath...@aol.com> wrote:
> >>> Dynamically loading script files to speed up the loading process?
> >>> Garbage.
> >>> What it will do, if done properly, is speed up the initial
> >>> rendering of the page. But it WON'T speed up load time of the
> >>> files and will actually slow it down. The reason it will
> >>> actually slow it down is because it has to do more work to
> >>> load the files. Whether the file is static coded or dynamically
> >>> loaded, the file still has to be downloaded from the server.
> >>> Want it to download faster? Make the file physically smaller.
> >>> Any other advice is magical hocus-pocus for making it load
> >>> faster if everything else is the same.
> >>> (...)
> >> I'm not sure why do you say so, as it's obvious (isn't it ?) that
> >> latency times add up when the scripts are loaded in series.
>
> > I say that because its patently true. Unless you want to try to
> > convince me that connection speed is determined by how the file
> > was attempted to be loaded. Again, take a HARD look at the original
> > script, how it was written, and how it would work. Then let's
> > discuss what it will or won't do.
>
> <script>s hardcoded in the source .html halt parsing and download in
> series, while dynamically inserted ones don't halt parsing and download
> in parallel.

And that is precisely what I said. It doesn't change the download time
it
takes, it changes the rendering time to render an initial page so that
you fool the uneducated into thinking the page has finished "loading"
because they see content. Witness mySpace and its abominable use of
AJAX to try to "speed up" the site when in fact its a classic example
of the *wrong way* to speed up a site.

> > Has John Resig gotten any clue about JS in the last 18 months or so?
> > If he hasn't, then he still doesn't have a clue.
>
> DM in disguise ?

That question, in and of itself, displays your level of knowledge
of what you are attempting to discuss. Try searching the archives
for the suggested search, read it all, and then get back to me.
Because as it stands now, your question shows that you have made
no effort to research the archives to find out about the subject
you are trying to portray yourself as an expert on.

I am not what I would consider an "expert" on the topic but I simply
have done a TON of research in the last 10 years or so on the topic
and a perusal of the archives would answer many of the questions you
are trying to - incorrectly - answer.

--
Randy Webb

Jorge

unread,
Jun 29, 2009, 4:14:46 AM6/29/09
to
On Jun 29, 8:11 am, One Dumm Hikk <hikksnotath...@aol.com> wrote:
> On Jun 28, 9:57 pm, Jorge <jo...@jorgechamorro.com> wrote:
> (...)

> > That f() must be a global and requires a previous, separate <script>.
> > Resig's solution requires none of these.
>
> Pure nonsense. It doesn't have to be global nor does it
> "require a previous, seperate <script>".
> f() can be a property of a single global object and the call
> can be made in the same file that you are loading. I know that
> to be true because its the way I have been doing it for many
> years now. Download a .js file that has data in it with a
> function call at the end of the file that deals with the
> data in the file.

Yes, the properties you attach to a global object are global too.
And yes, f() must have been declared somewhere (in a previous,
separate <script>) before calling it.

> That is how you deal with the issue of
> knowing when/if the file is downloaded or not. It is
> the ONLY *reliable* way to know that the data file has
> downloaded.
>
> Perhaps you should search the c.l.j archives for
> "dynamic script insertion" and spend the next two
> weeks or so reading the many many threads on this
> topic.

You mean, that perhaps, I'd find there something else that's not being
said here ?
A secret or something ?

Now it looks like you're focusing on the "doesn't halt parsing" aspect
while conveniently forgetting about the "and download in parallel
(read: faster)" side of things.

> Witness mySpace and its abominable use of
> AJAX to try to "speed up" the site when in fact its a classic example
> of the *wrong way* to speed up a site.
>
> > > Has John Resig gotten any clue about JS in the last 18 months or so?
> > > If he hasn't, then he still doesn't have a clue.
>
> > DM in disguise ?
>
> That question, in and of itself, displays your level of knowledge
> of what you are attempting to discuss. Try searching the archives
> for the suggested search, read it all, and then get back to me.
> Because as it stands now, your question shows that you have made
> no effort to research the archives to find out about the subject
> you are trying to portray yourself as an expert on.

How's posting code that proves what I say is pretending ?

> I am not what I would consider an "expert" on the topic but I simply
> have done a TON of research in the last 10 years or so on the topic
> and a perusal of the archives would answer many of the questions you
> are trying to - incorrectly - answer.
>
> --
> Randy Webb

--
Jorge.

Richard Cornford

unread,
Jun 29, 2009, 4:54:47 AM6/29/09
to
Jorge wrote:
> On Jun 29, 8:11 am, One Dumm Hikk wrote:

>> Jorge wrote:
>>> One Dumm Hikk wrote:
>>> That f() must be a global and requires a previous, separate
>>> <script>. Resig's solution requires none of these.
>>
>> Pure nonsense. It doesn't have to be global nor does it
>> "require a previous, seperate <script>".
>> f() can be a property of a single global object and the call
>> can be made in the same file that you are loading. I know that
>> to be true because its the way I have been doing it for many
>> years now. Download a .js file that has data in it with a
>> function call at the end of the file that deals with the
>> data in the file.
>
> Yes, the properties you attach to a global object are global too.

Only if you accept that the whole DOM and all 'namespacing' schemes have
results that are 'global'.

> And yes, f() must have been declared somewhere (in a previous,
> separate <script>) before calling it.

No. This - f - must be declared/assigned, and it must be a function if
it is to be called, but there is no reason that it could not have been
declared in the JS files that is being dynamically loaded. There is no
need for and previous or separate SCRIPT element.

<snip>


>> Perhaps you should search the c.l.j archives for
>> "dynamic script insertion" and spend the next two
>> weeks or so reading the many many threads on this
>> topic.
>
> You mean, that perhaps, I'd find there something else
> that's not being said here ?
> A secret or something ?

Anything that can be found in public archives is not secret. One thing
that would be seen by searching the archives is for how long this
subject has been being kicked around on this group. It is a sufficiently
old subject that some of us will remember the technique for dynamic
script insertion that worked with Netscape 4 (something that nobody
cares about at all these days).

<snip>


> Now it looks like you're focusing on the "doesn't halt parsing"
> aspect while conveniently forgetting about the "and download in
> parallel (read: faster)" side of things.

And you are stressing "parallel" when if the HTTP constraint on only
having two simultaneous connections to the server is in force the number
of resources that can be downloaded at the same time is limited to two.
The result is not parallels, it is just less serial than making the next
request after the resource for the last had been delivered (and possibly
not even then, depending on the demand for connections to download other
resources).

<snip>


> How's posting code that proves what I say is pretending ?

<snip>

How about posting explanations that state what it is you think the code
you are posting shows?

Richard.

Thomas 'PointedEars' Lahn

unread,
Jun 29, 2009, 5:03:58 AM6/29/09
to
Conrad Lender wrote:
> On 27/06/09 10:01, Garrett Smith wrote:
>> AISB, eval is called in global context. Steve did not mention this, and
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

>> the code is so naive that I doubt he is even aware of it, but the code
>> must exist in global context, or use a separate sandbox 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,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You are mistaken, as proven recently. Find the proof below again, in a more
elaborated form.

> and it also keeps the 'eval' out of the loader code, which makes
> minification easier:
>
> function evil (code) {
> return eval(code);

Now include variable declarations in `code'. Not only that the variables
will not be available globally afterwards, as I have showed; they will also
be deletable (as per Specification), as Martin has pointed out.

function isMethod(o, p)
{
if (/^\s*(undefined|unknown)\s*$/i.test(typeof o)) return false;

var t = typeof o[p];
return (/^\s*unknown\s*$/i.test(t)
|| /^\s*(function|object)\s*$/i.test(t) && o[p]);
}

function dmsg(s, bShow)
{
if (typeof console != "undefined"
&& isMethod(console, "log"))
{
console.log(s);
}
else if (bShow
&& typeof window != "undefined"
&& isMethod(window, "alert"))
{
window.alert(s);
}
}

function evil(code)
{
var result = eval(code);

/* 1. typeof x === "number" */
dmsg('1. typeof x === "' + typeof x + '"', true);

/* 2. typeof y === "number" */
dmsg('2. typeof y === "' + typeof y + '"', true);

delete x;

/* 3. typeof x === "undefined" */
dmsg('3. typeof x === "' + typeof x + '"', true);

/* 4. typeof y === "number" */
dmsg('4. typeof y === "' + typeof y + '"', true);

return result;
}

/* 5. evil(...) === 42 */
dmsg('5. evil(...) === ' + evil("var x = 1, y = 2; 42"), true);

/* 6. typeof y === "undefined" */
dmsg('6. typeof y === "' + typeof y + '"', true);


PointedEars

Jorge

unread,
Jun 29, 2009, 6:48:13 AM6/29/09
to
On Jun 29, 10:54 am, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:

> Jorge wrote:
> > On Jun 29, 8:11 am, One Dumm Hikk wrote:
> >> Jorge wrote:
> >>> One Dumm Hikk wrote:
> >>> That f() must be a global and requires a previous, separate
> >>> <script>. Resig's solution requires none of these.
>
> >> Pure nonsense. It doesn't have to be global nor does it
> >> "require a previous, seperate <script>".
> >> f() can be a property of a single global object and the call
> >> can be made in the same file that you are loading. I know that
> >> to be true because its the way I have been doing it for many
> >> years now. Download a .js file that has data in it with a
> >> function call at the end of the file that deals with the
> >> data in the file.
> > Yes, the properties you attach to a global object are global too.
>
> Only if you accept that the whole DOM and all 'namespacing' schemes have
> results that are 'global'.
>
> > And yes, f() must have been declared somewhere (in a previous,
> > separate <script>) before calling it.
>
> No. This - f - must be declared/assigned, and it must be a function if
> it is to be called, but there is no reason that it could not have been
> declared in the JS files that is being dynamically loaded. There is no
> need for and previous or separate SCRIPT element.

Yes it could be there but of course that has several drawbacks and it
would of course not be so convenient and flexible as the degrading
script's pattern where nothing is hardcoded in the script but the
location of the source to execute: its own .innerHTML.

> <snip>
>
> >> Perhaps you should search the c.l.j archives for
> >> "dynamic script insertion" and spend the next two
> >> weeks or so reading the many many threads on this
> >> topic.
>
> > You mean, that perhaps, I'd find there something else
> > that's not being said here ?
> > A secret or something ?
>
> Anything that can be found in public archives is not secret.

Also a secret that somebody reveals somewhere e.g. in a public archive
is still a secret, although a disclosed one.

> One thing
> that would be seen by searching the archives is for how long this
> subject has been being kicked around on this group. It is a sufficiently
> old subject that some of us will remember the technique for dynamic
> script insertion that worked with Netscape 4 (something that nobody
> cares about at all these days).

I have no doubt about this. But if I say a=b don't just tell me no+ go
search why, just tell me why not.

> <snip>
>
> > Now it looks like you're focusing on the "doesn't halt parsing"
> > aspect while conveniently forgetting about the "and download in
> > parallel (read: faster)" side of things.
>
> And you are stressing "parallel" when if the HTTP constraint on only
> having two simultaneous connections to the server is in force the number
> of resources that can be downloaded at the same time is limited to two.

No current browser has this limit set to 2, no matter what any
standard says. And no server either (neither ?).

> The result is not parallels, it is just less serial than making the next
> request after the resource for the last had been delivered (and possibly
> not even then, depending on the demand for connections to download other
> resources).

Haven't you seen the results of the tests in the links that I've
posted ?

> <snip>> How's posting code that proves what I say is pretending ?
>
> <snip>
>
> How about posting explanations that state what it is you think the code
> you are posting shows ?

Yeah, great. Thanks.

--
Jorge.

Jorge

unread,
Jun 29, 2009, 7:29:47 AM6/29/09
to
On Jun 28, 10:10 am, David Mark <dmark.cins...@gmail.com> wrote:
> On Jun 28, 3:37 am, Jorge <jo...@jorgechamorro.com> wrote:
>
> > Thanks, but AFAICS, an eval('code') at the top level is ===
> > <script>'code'</script> :
>
> > - 'this' === window,
>
> Bad assumption, but irrelevant here.

Bad assumption ? At the top level ? in a browser ? How so ?

<script>alert(this === window);</script>

> > - [[scope]] === global context, and
>
> Not exactly.

What else is in the scope chain at the top level ?

> And are you planning to run this XHR/eval combo in the global
> context? I would expect it to reside in a function.

Yes it will very likely most often be isolated into a (function()
{'code'})(); context capsule;

> > - no Variable 'object'.
>
> See above.

You too.

--
Jorge.

Jorge

unread,
Jun 29, 2009, 7:38:21 AM6/29/09
to
On Jun 28, 3:05 pm, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
>
> > 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.

Times are changin', see it by yourself:

http://jorgechamorro.com/cljs/071/

In at least Safari 4, FF3.5b and Opera 10b.

--
Jorge.

Jorge

unread,
Jun 29, 2009, 8:06:11 AM6/29/09
to
On Jun 29, 5:59 am, Conrad Lender <crlen...@yahoo.com> wrote:
> On 29/06/09 04:22, Jorge wrote:
>
> > Conrad Lender wrote:
> >> 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.
>
> > They've got "their" own FAQ, I've got my own posts... :-)
>
> Suit yourself, but it appears that some people are getting annoyed by
> your additions.

They certainly shouldn't, it's so irrational, but as they've got that
superiority complex about anything-Crockford...
I mean, the usual bunch of conceited, bigoted regulars, it's pitiful.

--
Jorge.

Richard Cornford

unread,
Jun 29, 2009, 8:15:12 AM6/29/09
to
On Jun 29, 12:38 pm, Jorge wrote:

> On Jun 28, 3:05 pm, Richard Cornford wrote:
>>> 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.
>
> Times are changin', see it by yourself:
>
> http://jorgechamorro.com/cljs/071/
>
> In at least Safari 4, FF3.5b and Opera 10b.

See what for myself? In what way does this demonstrate the use of -
document.wirte - to create script elements with SRC references to
external resources failing to halt the HTML parser?

Richard.

Jorge

unread,
Jun 29, 2009, 8:21:10 AM6/29/09
to

Read again:

"By making them dynamically declared script elements (either using
document.write or dynamic SCRIPT elements), it allows

**concurrent**loading** with other elements."

--
Jorge.

Richard Cornford

unread,
Jun 29, 2009, 8:32:55 AM6/29/09
to
On Jun 29, 1:21 pm, Jorge <jo...@jorgechamorro.com> wrote:
> Richard Cornford wrote:
>> On Jun 29, 12:38 pm, Jorge wrote:
>>> On Jun 28, 3:05 pm, Richard Cornford wrote:
>>>>> 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.
>>> Times are changin', see it by yourself:
>
>>>http://jorgechamorro.com/cljs/071/
>
>>> In at least Safari 4, FF3.5b and Opera 10b.
>
>> See what for myself?  In what way does this demonstrate the use of -
>> document.wirte - to create script elements with SRC references to
>> external resources failing to halt the HTML parser?
>
> Read again:

Read what again?

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

Richard.

Jorge

unread,
Jun 29, 2009, 9:37:18 AM6/29/09
to
On Jun 29, 2:32 pm, Richard Cornford <Rich...@litotes.demon.co.uk>
wrote:

In that it takes 1/4th the time ?
In that the network throughput grows 4x ?
Are you kidding ?

--
Jorge.

Richard Cornford

unread,
Jun 29, 2009, 10:04:31 AM6/29/09
to
On Jun 29, 2:37 pm, Jorge wrote:
> On Jun 29, 2:32 pm, Richard Cornford wrote:

>> On Jun 29, 1:21 pm, Jorge wrote:
>>> Richard Cornford wrote:
>>>> On Jun 29, 12:38 pm, Jorge wrote:
>>>>> On Jun 28, 3:05 pm, Richard Cornford wrote:
>>>>>>> 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.
>>>>> Times are changin', see it by yourself:
>
>>>>>http://jorgechamorro.com/cljs/071/
>
>>>>> In at least Safari 4, FF3.5b and Opera 10b.
>
>>>> See what for myself? In what way does this demonstrate the use
>>>> of - document.wirte - to create script elements with SRC
>>>> references to external resources failing to halt the HTML parser?
>
>> > Read again:
>
>> Read what again?
>
>>> "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?
>
> In that it takes 1/4th the time ?

What is the "it" that takes 1/4 of the time? And in what way does that
provide evidence for concurrent loading?

> In that the network throughput grows 4x ?
> Are you kidding ?

No, I am asking questions. So far you are not answering any of them
(or even trying to).

Richard.

Jorge

unread,
Jun 29, 2009, 10:39:05 AM6/29/09
to
Richard Cornford wrote:
> (...)

Grrrr + :-(
--
Jorge.

rf

unread,
Jun 29, 2009, 11:02:23 AM6/29/09
to
Jorge wrote:
> Richard Cornford wrote:
>> (...)
>
> Grrrr + :-(

WTF are you growling about?

And no, I'm not going to search the thread to find out.


Jorge

unread,
Jun 29, 2009, 12:26:02 PM6/29/09
to
On Jun 29, 5:02 pm, "rf" <r...@z.invalid> wrote:
> Jorge wrote:
> > Richard Cornford wrote:
> >> (...)
>
> > Grrrr  +  :-(
>
> WTF are you growling about ?

About (...), WTF !

--
Jorge.

Conrad Lender

unread,
Jun 29, 2009, 1:18:53 PM6/29/09
to
On 29/06/09 11:03, Thomas 'PointedEars' Lahn wrote:

> Conrad Lender 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,
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> You are mistaken, as proven recently. Find the proof below again, in a more
> elaborated form.
>
>> and it also keeps the 'eval' out of the loader code, which makes
>> minification easier:
>>
>> function evil (code) {
>> return eval(code);
>
> Now include variable declarations in `code'. Not only that the variables
> will not be available globally afterwards, as I have showed; they will also
> be deletable (as per Specification), as Martin has pointed out.

[snip code]

I'm not too worried about the variables being 'delete'd - this rarely
happens and can be avoided - but I see your point about global
availability, and now I remember why I didn't use this form myself. Your
example nicely demonstrates "what's so bad about" just moving the 'eval'
to a separate function. It will only work if the evaluated script
doesn't declare new global variables, or if these variables are never
accessed outside the included script. It's possible to make it work with
this restriction, but it's very limited, and not a good general solution.

What I have been using is execScript(), if available, or else
window.eval, if available. I'm not happy with this solution, because
both are nonstandard, and not guaranteed to work (IIRC, window.eval is
even guaranteed *not* to work in ES5 strict mode). I wouldn't be
surprised if there were reasonably current UAs which support neither.

There's a lot about this topic on the web, and in the group archives.
Has there ever been a consensus in this group about the best/safest way
to evaluate code in global context?


- Conrad

David Mark

unread,
Jun 29, 2009, 3:26:27 PM6/29/09
to
On Jun 29, 7:29 am, Jorge <jo...@jorgechamorro.com> wrote:
> On Jun 28, 10:10 am, David Mark <dmark.cins...@gmail.com> wrote:
>
> > On Jun 28, 3:37 am, Jorge <jo...@jorgechamorro.com> wrote:
>
> > > Thanks, but AFAICS, an eval('code') at the top level is ===
> > > <script>'code'</script> :
>
> > > - 'this' === window,
>
> > Bad assumption, but irrelevant here.
>
> Bad assumption ? At the top level ? in a browser ? How so ?

For all intents and purposes, this thread was over days ago. Why are
you still in here going around in circles like a puppy chasing its
tail (and periodically getting smacked on the nose for the
annoyance.) You are really fouling up everything for casual readers.

>
> <script>alert(this === window);</script>

For seemingly the 8 millionth time, in browsers, the global window
property is sometimes a reference to the Global Object, but you should
not (and don't need to) assume that.

[snip]

We're done here, Jorge. All of the answers are at the end of your
nose.

David Mark

unread,
Jun 29, 2009, 3:32:49 PM6/29/09
to

Neither of those are acceptable.

>
> There's a lot about this topic on the web, and in the group archives.
> Has there ever been a consensus in this group about the best/safest way
> to evaluate code in global context?

As have been mentioned in this thread, search the archive for "dynamic
script injection" (and/or "Webb.") You don't need execScript and
shouldn't use window.eval under any circumstances.

Conrad Lender

unread,
Jun 29, 2009, 4:32:23 PM6/29/09
to
On 29/06/09 21:32, David Mark wrote:
> On Jun 29, 1:18 pm, Conrad Lender <crlen...@yahoo.com> wrote:
>> What I have been using is execScript(), if available, or else
>> window.eval, if available. I'm not happy with this solution, because
>> both are nonstandard, and not guaranteed to work (IIRC, window.eval is
>> even guaranteed *not* to work in ES5 strict mode). I wouldn't be
>> surprised if there were reasonably current UAs which support neither.
>
> Neither of those are acceptable.

Yes, I just said that.

>> There's a lot about this topic on the web, and in the group archives.
>> Has there ever been a consensus in this group about the best/safest way
>> to evaluate code in global context?
>
> As have been mentioned in this thread, search the archive for "dynamic
> script injection" (and/or "Webb.")

The problem is that there has been so much discussion about it that it
makes the relevant bits hard to find. If this has been discussed so
much, and is frequently asked, it should probably go in the FAQ, which
would save people from sifting through thousands of posts containing
half-solutions and esoteric cases every time.

Is it really too much to ask which is the "recommended" approach? Is it
creating a script element, setting its .type, adding the code as its
.text, and appending it to the body? Which problems can be expected with
this approach? Is window.setTimeout(code, 0) equivalent, as long as
setTimeout is available, and order of execution doesn't matter? I don't
mind doing research, but I do mind the "I know, but I won't tell" attitude.


- Conrad

David Mark

unread,
Jun 29, 2009, 4:48:56 PM6/29/09
to
On Jun 29, 4:32 pm, Conrad Lender <crlen...@yahoo.com> wrote:
> On 29/06/09 21:32, David Mark wrote:
>
> > On Jun 29, 1:18 pm, Conrad Lender <crlen...@yahoo.com> wrote:
> >> What I have been using is execScript(), if available, or else
> >> window.eval, if available. I'm not happy with this solution, because
> >> both are nonstandard, and not guaranteed to work (IIRC, window.eval is
> >> even guaranteed *not* to work in ES5 strict mode). I wouldn't be
> >> surprised if there were reasonably current UAs which support neither.
>
> > Neither of those are acceptable.
>
> Yes, I just said that.

You said you were using them as well, which is not acceptable.

>
> >> There's a lot about this topic on the web, and in the group archives.
> >> Has there ever been a consensus in this group about the best/safest way
> >> to evaluate code in global context?
>
> > As have been mentioned in this thread, search the archive for "dynamic
> > script injection" (and/or "Webb.")
>
> The problem is that there has been so much discussion about it that it
> makes the relevant bits hard to find. If this has been discussed so

Not really.

> much, and is frequently asked, it should probably go in the FAQ, which

Tell the FAQ maintainer.

> would save people from sifting through thousands of posts containing
> half-solutions and esoteric cases every time.

I told you whose posts to read. Skip to the end.

>
> Is it really too much to ask which is the "recommended" approach? Is it

I told you.

> creating a script element, setting its .type, adding the code as its
> .text, and appending it to the body? Which problems can be expected with

That's one of three ways and you have to feature test to determine
which will succeed (if any.) I know I mentioned in this thread that
there is a method in My Library for this. Just type "browser
scripting library" into your favorite search engine (it's invariably
the top result.)

> this approach? Is window.setTimeout(code, 0) equivalent, as long as
> setTimeout is available, and order of execution doesn't matter?

Of course not. For one, the idea is to execute the script
immediately.

> I don't
> mind doing research, but I do mind the "I know, but I won't tell" attitude.

That attitude is in all in your head. You could search the archive,
see my example, Google for Randy's examples, etc. In browser time,
this is all ancient history. It's not up to others to give you
answers on a silver platter either (this is not a help desk.)

Dr J R Stockton

unread,
Jun 29, 2009, 5:55:19 PM6/29/09
to
In comp.lang.javascript message <aca954a0-7e87-42d6-81fd-6ae2325bfad5@l5
g2000vbp.googlegroups.com>, Fri, 26 Jun 2009 18:49:05, One Dumm Hikk
<hikksno...@aol.com> posted:

I see the reappearance of a dropout.

--
(c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 7.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
I find MiniTrue useful for viewing/searching/altering files, at a DOS prompt;
free, DOS/Win/UNIX, <URL:http://www.idiotsdelight.net/minitrue/> unsupported.

David Mark

unread,
Jun 29, 2009, 8:55:18 PM6/29/09
to
On Jun 29, 5:55 pm, Dr J R Stockton <reply0...@merlyn.demon.co.uk>
wrote:

> In comp.lang.javascript message <aca954a0-7e87-42d6-81fd-6ae2325bfad5@l5
> g2000vbp.googlegroups.com>, Fri, 26 Jun 2009 18:49:05, One Dumm Hikk
> <hikksnotath...@aol.com> posted:

>
> I see the reappearance of a dropout.
>

You really take the cake, Johnny. I'll speculate wildly and say he
got tired of listening to your shit. But the main point is that you
have no idea why anyone posts here (or not.)

Please try to stay on topic. It's a good idea to read the newsgroup
and its FAQ, etc.

One Dumm Hikk

unread,
Jun 30, 2009, 4:46:49 AM6/30/09
to

Don't waste your time on him, he isn't worth
the effort. I stopped posting here for personal
reasons (health mostly). The only reason I am
back now is because Michael emailed me (CC
actually) and pointed me to the thread.
My GG account had even lapsed.

Jorge, if you want to truly discuss the aspects
of dynamically loading scripts, email me. I
don't have an issue discussing it as long as
it stays a constructive discussion and stays
away from this "My approach is perfect" non-
sense. I can tell you the flaws in the
approach I use, and ways around them. How many
people that use/wrote jQuery and the likes
can do that?
My goal isn't to become the "leading expert"
on the topic but rather to keep learning the
topic as I use dynamic loading exclusively on
an Intranet setting.

I just hate and despise the GG interface(mostly
that annoying ass captcha pos thingie) and
not setting up a new Usenet account just for
this discussion unless people truly show that
they want to discuss it instead of all the
"I am right" crap thats going on.

Randy

Jorge

unread,
Jun 30, 2009, 6:56:42 AM6/30/09
to
Conrad Lender wrote
> (...)

> Is it really too much to ask which is the "recommended" approach? Is it
> creating a script element, setting its .type, adding the code as its
> ..text, and appending it to the body? Which problems can be expected with

> this approach? Is window.setTimeout(code, 0) equivalent, as long as
> setTimeout is available, and order of execution doesn't matter?

Good question.

1.- Create and insert an <script>'code'</script>

2.- Use myEval= eval; myEval('code');

3.- Use window.eval().

4.- Use setTimeout('code', 0);

5.- function gEval (code) {
with (window) {
return eval(code);
}
}

6.- ?

2 and 3 are unreliable because so many browsers still scope the eval in
the current context. 5 is an idea I've had while writing this. 4 is for
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 ?

--
Jorge

Dr J R Stockton

unread,
Jun 30, 2009, 2:46:11 PM6/30/09
to
In comp.lang.javascript message <48d78707-9188-4c24-8be3-01d8d6f62fc2@f1
6g2000vbf.googlegroups.com>, Mon, 29 Jun 2009 17:55:18, David Mark
<dmark....@gmail.com> posted:

We know that he abandoned his agreed task of FAQ maintainer without the
courtesy of posting a resignation to the group. For that, death or a
reasonable approximation thereof is the only honourable excuse.

But abandoning agreed responsibilities seems to be a national custom
over there; consider for example what happened to the moderated Y2k
newsgroup.

Perhaps I should do here as I have done in other groups : kill-rule
@gmail - it does make things more pleasant, by getting rid of such a
large proportion of the puerile and comparatively few unknown others
(known others can have a preceding accept rule; unknowns usually get
seen by quotation).

--
(c) John Stockton, nr London UK. ???@merlyn.demon.co.uk Turnpike v6.05 MIME.


Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.

Check boilerplate spelling -- error is a public sign of incompetence.
Never fully trust an article from a poster who gives no full real name.

kangax

unread,
Jul 4, 2009, 12:28:35 AM7/4/09
to
Jorge wrote:
> Conrad Lender wrote
>> (...)
>> Is it really too much to ask which is the "recommended" approach? Is it
>> creating a script element, setting its .type, adding the code as its
>> ..text, and appending it to the body? Which problems can be expected with
>> this approach? Is window.setTimeout(code, 0) equivalent, as long as
>> setTimeout is available, and order of execution doesn't matter?
>
> Good question.
>
> 1.- Create and insert an <script>'code'</script>
>
> 2.- Use myEval= eval; myEval('code');
>
> 3.- Use window.eval().
>
> 4.- Use setTimeout('code', 0);
>
> 5.- function gEval (code) {
> with (window) {
> return eval(code);
> }
> }
>
> 6.- ?
>
> 2 and 3 are unreliable because so many browsers still scope the eval in
> the current context. 5 is an idea I've had while writing this. 4 is for

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.

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

--
kangax

Jorge

unread,
Jul 4, 2009, 6:51:40 AM7/4/09
to

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(),
... ?

--
Jorge.

kangax

unread,
Jul 4, 2009, 1:17:27 PM7/4/09
to

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.

[1] Pagetest <https://sourceforge.net/projects/pagetest/>
[2] HTTPWatch <http://www.httpwatch.com/>
[3] Firebug <https://addons.mozilla.org/en-US/firefox/addon/1843>

[4] Firebug's net panel
<https://addons.mozilla.org/en-US/firefox/images/p/11828/943948800>

--
kangax

kangax

unread,
Jul 4, 2009, 11:56:59 PM7/4/09
to
Jorge wrote:
> On Jul 4, 6:28 am, kangax <kan...@gmail.com> wrote:
>> 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 :)

>
> :-)
>
> What other eval-like methods exist ?
>
> -eval(),
> -setTimeout,
> -Function(),
> ... ?

`eval` and `new Function` as part of ES3. `setTimeout` and `setInterval`
as part of DOM (L0?). And then there are non-standard/proprietary ones
like `window.execScript`, `Object.prototype.eval` (now deprecated), etc.

--
kangax

Garrett Smith

unread,
Jul 5, 2009, 4:35:35 AM7/5/09
to
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

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

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

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

>> IIRC, The "Why Slow" Or 'yslow' extension for Firefox demonstrates
>> this.
>
> That using - document.wirte - results in asynchronous script downloading?
>
>> I forget how they tested the other browsers.
>
> 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
--
comp.lang.javascript FAQ: http://jibbering.com/faq/

Garrett Smith

unread,
Jul 5, 2009, 12:29:34 PM7/5/09
to
Conrad Lender wrote:
> On 27/06/09 10:01, Garrett Smith wrote:
>> <FAQENTRY>
>> Q: I saw a video online. Why wasn't it in the FAQ?
>> A: Video presentations often contain advice that is either
>> incorrect or inadvisable. It possible, though unlikely, that the video
>> has not been reviewed and contains accurate and valuable information.
>> Before posting a request for review, please search the archives for
>> discussion about the video.
>> </FAQENTRY>
>
> 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.
>
>> Steve:
> ...
>> | I get all the script elements, I loop through them, until I find the
>> | script whose name is "menu jay", "menu-degrading.js" and then I look
>> | at its innerHMTL property.
>
> 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.

>> None of the three reasons is true. All are blatantly false and in being
>> false, they serve as reasons for eschewing this technique.
>
> 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.

>> AISB, eval is called in global context. Steve did not mention this, and
>> the code is so naive that I doubt he is even aware of it, but the code
>> must exist in global context, or use a separate sandbox 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);
>
>> Another problem with eval is that when an EvalError occurs, the browser
>> may not provide information about what was being eval'd that caused the
>> problem. Instead, the browser will state that eval(s) caused a problem.
>> Since eval can't be stepped into, it is harder to debug.
>
> 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 is less clear, more complicated because it
>> requires more code inside menuteir.js to execute the inline script
>> content. The menuteir.js should not be have knowledge of the performance
>> tricks used to include it. It severely complicates things; it does not
>> make things simpler, nor clearer.
>
> 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.
>
>> The "Managed XHR" solution also requires eval, and has all the
>> complications associated with that, just as in Dojo.
>
> 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.

>> Technique 4 Script onload aka "The Best One", shows code that modifies
>> Host objects with expandos. For reasons that have been discussed here
>> many times, code which modifies host objects is error prone.
>
> 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".


>> I do agree that this deserves mention in the FAQ. If Steve's book is
>> going to be included, it ought to mention that his application design
>> advice is considerably harmful.
>
> 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.

Jorge

unread,
Jul 5, 2009, 4:56:18 PM7/5/09
to
Garrett Smith wrote:
> (...)

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

--
Jorge.

Jorge

unread,
Jul 5, 2009, 5:13:26 PM7/5/09
to
kangax wrote:
> Jorge wrote:
>> On Jul 4, 6:28 am, kangax <kan...@gmail.com> wrote:
>>> 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...

--
Jorge

Garrett Smith

unread,
Jul 5, 2009, 7:21:53 PM7/5/09
to
Jorge wrote:
> Garrett Smith wrote:
>> (...)
>> 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 ?
>

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

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

This came up earlier.

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

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 Smith

unread,
Jul 5, 2009, 7:26:00 PM7/5/09
to
Garrett Smith wrote:
> Conrad Lender wrote:
>> 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;");

kangax

unread,
Jul 5, 2009, 9:42:18 PM7/5/09
to
David Mark wrote:

> On Jun 28, 3:02 am, kangax <kan...@gmail.com> wrote:
>> David Mark wrote:
>>> On Jun 25, 3:30 pm, Conrad Lender <crlen...@yahoo.com> wrote:
>> [...]
>>>> David Mark will probably kill me right about now, because Steve Souders
>>>> works at Google, and nothing good has ever come from that company,
>>> Well, Google has never published a single competent line of Javascript
>>> (or Website AFAICT.) You make the call.
>> You are probably talking about browser scripting.
>
> Of course.
>
>> There's a Caja project that Google is working on - a secure subset of
>> ES3 implemented in ES3 itself. Some of the code in it is state of the
>> art and is very far from being incompetent. If you look at one of the
>> Caja's base scripts - cajita.js
>> <http://code.google.com/p/google-caja/source/browse/trunk/src/com/goog...>,
>> you will quickly realize that implementing such environment requires a
>> truly deep understanding of ECMAScript internals.
>
> // Copyright (C) 2007 Google Inc.
> //
> // Licensed under the Apache License, Version 2.0 (the "License");
> // you may not use this file except in compliance with the License.
> // You may obtain a copy of the License at
> //
> // http://www.apache.org/licenses/LICENSE-2.0
> //
> // Unless required by applicable law or agreed to in writing, software
> // distributed under the License is distributed on an "AS IS" BASIS,
> // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> // See the License for the specific language governing permissions and
> // limitations under the License.
>
> /**
> * @fileoverview the Cajita runtime library.
> * It is written in Javascript, not Cajita, and would be rejected by
> the Cajita
> * translator. This module exports two globals:<ol>
> * <li>"___" for use by the output of the Cajita translator and by
> some
> * other untranslated Javascript code.
> * <li>"cajita" providing some common services to the Cajita
> programmer.
> * </ol>
> * @author eri...@gmail.com
> * @requires console
> * @provides ___, arraySlice, cajita, dateToISOString, funcBind
> * @overrides Array, Boolean, Date, Function, Number, Object, RegExp,
> String
> * @overrides Error, EvalError, RangeError, ReferenceError,
> SyntaxError,
> * TypeError, URIError
> */
>
> // TODO(erights): All code text in comments should be enclosed in
> // {@code ...}.
>
> // TODO(ihab.awad): Missing tests in CajitaTest.java for the
> functionality
> // in this file.
>
> I guess this is unfinished. (?)

Yes, it's a work in progress, afaik.

>
>
> // Add a tag to whitelisted builtin constructors so we can check the
> class
> // cross-frame. Note that Function is not on the list.
>
> Array.typeTag___ = 'Array';
> Object.typeTag___ = 'Object';
> String.typeTag___ = 'String';
> Boolean.typeTag___ = 'Boolean';
> Number.typeTag___ = 'Number';
> Date.typeTag___ = 'Date';
> RegExp.typeTag___ = 'RegExp';
> Error.typeTag___ = 'Error';
> EvalError.typeTag___ = 'EvalError';
> RangeError.typeTag___ = 'RangeError';
> ReferenceError.typeTag___ = 'ReferenceError';
> SyntaxError.typeTag___ = 'SyntaxError';
> TypeError.typeTag___ = 'TypeError';
> URIError.typeTag___ = 'URIError';
>
> Whatever this is setting up, I'm sure I won't like it. I stopped
> reading at this point.

That's an (arguably) necessary augmentation of built-in (not host)
objects for such environment. Look further, there's plenty of
interesting code in there.

[...]

>> Speaking of ECMAScript internals, one of
>> the Caja members - Mark Miller - is also one of ES committee members and
>
> Of the "Miller Device", which turned out to be incompatible with IE?

Miller Device, yes. Funny that I found this "technique" few month
earlier than him, but that doesn't matter much now.

> And "ES committee member" is no badge of honor (isn't Resig on that
> list?)

He's not, AFAIK. Anyone can join ES mailing list, though.

>
>> played quite a big role in developing (currently draft) ES5.
>
> He's doing a hell of job from what I've heard. :(

What do you mean?

>
>> Google might not be competent in client-side scripting, but I can't say
>> the same about their ES-as-a-language skills.
>
> That's as maybe. But why don't they get some of these ES luminaries
> to rewrite their grade Z browser scripts? Aren't they in the business
> of publishing Websites?

Good question. Apparently it "works" for them.

--
kangax

Jorge

unread,
Jul 6, 2009, 4:07:03 AM7/6/09
to
On Jul 6, 3:42 am, kangax <kan...@gmail.com> wrote:
> (...)

> Miller Device, yes. Funny that I found this "technique" few month
> earlier than him, but that doesn't matter much now.
> (...)

Sure ?
The date of that (1) in your site is January, 10th 2009, but
Crockford's blog entry about the Miller Device (2) came 4 months
before: October 9th, 2008.

(1)
http://thinkweb2.com/projects/prototype/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
(2)
<http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?
p=916>

--
Jorge.

David Mark

unread,
Jul 6, 2009, 4:49:00 AM7/6/09
to
> > //http://www.apache.org/licenses/LICENSE-2.0

> > //
> > // Unless required by applicable law or agreed to in writing, software
> > // distributed under the License is distributed on an "AS IS" BASIS,
> > // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> > implied.
> > // See the License for the specific language governing permissions and
> > // limitations under the License.
>
> > /**
> >  * @fileoverview the Cajita runtime library.
> >  * It is written in Javascript, not Cajita, and would be rejected by
> > the Cajita
> >  * translator. This module exports two globals:<ol>
> >  * <li>"___" for use by the output of the Cajita translator and by
> > some
> >  *     other untranslated Javascript code.
> >  * <li>"cajita" providing some common services to the Cajita
> > programmer.
> >  * </ol>
> >  * @author erig...@gmail.com

> >  * @requires console
> >  * @provides ___, arraySlice, cajita, dateToISOString, funcBind
> >  * @overrides Array, Boolean, Date, Function, Number, Object, RegExp,
> > String
> >  * @overrides Error, EvalError, RangeError, ReferenceError,
> > SyntaxError,
> >  *   TypeError, URIError
> >  */
>
> > // TODO(erights): All code text in comments should be enclosed in
> > // {@code ...}.
>
> > // TODO(ihab.awad): Missing tests in CajitaTest.java for the
> > functionality
> > // in this file.
>
> > I guess this is unfinished. (?)
>
> Yes, it's a work in progress, afaik.

Looks like it was abandoned in 2007.

>
>
>
>
>
> > // Add a tag to whitelisted builtin constructors so we can check the
> > class
> > // cross-frame. Note that Function is not on the list.
>
> > Array.typeTag___ = 'Array';
> > Object.typeTag___ = 'Object';
> > String.typeTag___ = 'String';
> > Boolean.typeTag___ = 'Boolean';
> > Number.typeTag___ = 'Number';
> > Date.typeTag___ = 'Date';
> > RegExp.typeTag___ = 'RegExp';
> > Error.typeTag___ = 'Error';
> > EvalError.typeTag___ = 'EvalError';
> > RangeError.typeTag___ = 'RangeError';
> > ReferenceError.typeTag___ = 'ReferenceError';
> > SyntaxError.typeTag___ = 'SyntaxError';
> > TypeError.typeTag___ = 'TypeError';
> > URIError.typeTag___ = 'URIError';
>
> > Whatever this is setting up, I'm sure I won't like it.  I stopped
> > reading at this point.
>
> That's an (arguably) necessary augmentation of built-in (not host)
> objects for such environment. Look further, there's plenty of
> interesting code in there.

I glanced at it and saw references to these flags. I don't buy that
they are necessary.

>
> [...]
>
> >> Speaking of ECMAScript internals, one of
> >> the Caja members - Mark Miller - is also one of ES committee members and
>
> > Of the "Miller Device", which turned out to be incompatible with IE?
>
> Miller Device, yes. Funny that I found this "technique" few month
> earlier than him, but that doesn't matter much now.

The thing is, you should never need such a thing.

>
> > And "ES committee member" is no badge of honor (isn't Resig on that
> > list?)
>
> He's not, AFAIK. Anyone can join ES mailing list, though.

Is that was his fans mean when they throw up his "contributions" to ES
as an excuse for knowing nothing about it (nonsense intentional.)

>
>
>
> >>   played quite a big role in developing (currently draft) ES5.
>
> > He's doing a hell of job from what I've heard.  :(
>
> What do you mean?

Means I've heard nothing good about that draft.

>
>
>
> >> Google might not be competent in client-side scripting, but I can't say
> >> the same about their ES-as-a-language skills.
>
> > That's as maybe.  But why don't they get some of these ES luminaries
> > to rewrite their grade Z browser scripts?  Aren't they in the business
> > of publishing Websites?
>
> Good question. Apparently it "works" for them.

Yes, it "just works." Inspiration for losers everywhere. Too bad
they aren't Google or it might work for them too. ;)

kangax

unread,
Jul 6, 2009, 8:46:56 AM7/6/09
to

It was already in my repository on June 09, 2008 (see date of commit
with "reorganize" message)
<http://github.com/kangax/protolicious/blob/26a3893fd536eca6a443532d3394795fa02e00f4/experimental/__getClass.js>

I just never got a chance to write about it till January of next year :)

--
kangax

Jorge

unread,
Jul 6, 2009, 11:23:22 AM7/6/09
to

Hmm, Googling for the trick I found this: 2007-06-21:

http://krijnhoetmer.nl/irc-logs/whatwg/20070621

"<Philip`> Ooh, I never knew you could do something like
Object.prototype.toString.call(ctx) to work out the [[Class]] of an object"

:-)
--
Jorge

kangax

unread,
Jul 7, 2009, 12:56:03 AM7/7/09
to
David Mark wrote:
> On Jul 5, 9:42 pm, kangax <kan...@gmail.com> wrote:
>> David Mark wrote:
>>> On Jun 28, 3:02 am, kangax <kan...@gmail.com> wrote:
[...]
>>>> Speaking of ECMAScript internals, one of
>>>> the Caja members - Mark Miller - is also one of ES committee members and
>>> Of the "Miller Device", which turned out to be incompatible with IE?
>> Miller Device, yes. Funny that I found this "technique" few month
>> earlier than him, but that doesn't matter much now.
>
> The thing is, you should never need such a thing.

Then why are you using it in your dojo branch?
<http://trac.dojotoolkit.org/browser/branches/featureDetection/dojo/dojo.js#L945>

Are you talking about checking `length` property instead? Or checking
that property's type (i.e. number)? Or something else?

Btw, it looks like you have a typo in `dojo.areNSFeatures`
<http://trac.dojotoolkit.org/browser/branches/featureDetection/dojo/dojo.js#L146>

`var features = Array.prototype.slice(arguments, 1);`

should probably be:

`var features = Array.prototype.slice.call(arguments, 1);`

Strange that unit tests didn't catch this.

>
>>> And "ES committee member" is no badge of honor (isn't Resig on that
>>> list?)
>> He's not, AFAIK. Anyone can join ES mailing list, though.
>
> Is that was his fans mean when they throw up his "contributions" to ES
> as an excuse for knowing nothing about it (nonsense intentional.)
>
>>
>>
>>>> played quite a big role in developing (currently draft) ES5.
>>> He's doing a hell of job from what I've heard. :(
>> What do you mean?
>
> Means I've heard nothing good about that draft.

I think it's pretty good. It does alleviate some of the ES3 problems,
after all.

[...]

--
kangax

David Mark

unread,
Jul 7, 2009, 7:03:48 PM7/7/09
to
On Jul 7, 12:56 am, kangax <kan...@gmail.com> wrote:
> David Mark wrote:
> > On Jul 5, 9:42 pm, kangax <kan...@gmail.com> wrote:
> >> David Mark wrote:
> >>> On Jun 28, 3:02 am, kangax <kan...@gmail.com> wrote:
> [...]
> >>>> Speaking of ECMAScript internals, one of
> >>>> the Caja members - Mark Miller - is also one of ES committee members and
> >>> Of the "Miller Device", which turned out to be incompatible with IE?
> >> Miller Device, yes. Funny that I found this "technique" few month
> >> earlier than him, but that doesn't matter much now.
>
> > The thing is, you should never need such a thing.
>
> Then why are you using it in your dojo branch?
> <http://trac.dojotoolkit.org/browser/branches/featureDetection/dojo/do...>

>
> Are you talking about checking `length` property instead? Or checking
> that property's type (i.e. number)? Or something else?
>
> Btw, it looks like you have a typo in `dojo.areNSFeatures`
> <http://trac.dojotoolkit.org/browser/branches/featureDetection/dojo/do...>

>
> `var features = Array.prototype.slice(arguments, 1);`
>
> should probably be:
>
> `var features = Array.prototype.slice.call(arguments, 1);`

One of many at this point, I'm sure. Thanks for pointing it out.

>
> Strange that unit tests didn't catch this.

It's a temporary function I threw in a day or two ago. As for the
unit tests, they are looking pretty good as of yesterday. I made
about 10,000 changes without looking and virtually all of them broke.
Fixed a couple of typos and they are pretty much back to normal.
Another day or two and they will be perfect (assuming all of the tests
were valid to begin with.)

>
>
>
> >>> And "ES committee member" is no badge of honor (isn't Resig on that
> >>> list?)
> >> He's not, AFAIK. Anyone can join ES mailing list, though.
>
> > Is that was his fans mean when they throw up his "contributions" to ES
> > as an excuse for knowing nothing about it (nonsense intentional.)
>
> >>>>   played quite a big role in developing (currently draft) ES5.
> >>> He's doing a hell of job from what I've heard.  :(
> >> What do you mean?
>
> > Means I've heard nothing good about that draft.
>
> I think it's pretty good. It does alleviate some of the ES3 problems,
> after all.
>

Depends on your perspective.

Richard Cornford

unread,
Jul 12, 2009, 10:47:46 AM7/12/09
to
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.)

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

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

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

That was tried by a an early release of Netscape 6, and it did break a
number of sites and so got abandoned as an unrealistic idea.

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

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

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

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

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

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

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

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

> This means a LINK can effectively be another "blocking resource".

Can be, but does not have to be.

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

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

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

Richard.

Richard Cornford

unread,
Jul 12, 2009, 10:47:47 AM7/12/09
to
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.

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 have
all happened the script is unambiguously "loaded".

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

Monitoring HTTP traffic may tell you something about steps 1 and 2, but
it is not the whole picture.

Suppose a document contains two consecutive SCRIPT elements that both -
document.write - new SCRIPT elements that have SRC attributes that
reference 'scriptA' and 'scriptD' respectively. And additionally, that
'scriptA' uses - document.write - to create another SCRIPT element that
references 'scriptB' in its SRC attribute, and that 'scrtiptB' did yet
another - doument.wirte - to create a SCRIPT element that references
'scriptC'.

"Correct" operation would necessitate that the global variable
instantiation and execution of the global code for 'scriptC' happen
before the same happened for 'scriptD', yet the whole loading process
has to be completed for both 'scriptA' and 'scriptB' before the SCRIPT
element calling for 'scriptC' is created. Thus, the use of -
document.write - in the first SCRIPT element in the document has little
choice but block at least some aspects of the processing of the
following SCRIPT element.

The order in which some things get referenced in HTML documents matters.
Obviously for scripts themselves but certainly also CSS, and as scripts
have the option of creating STYLE and LINK elements with -
document.write - the potential for playing fast and loose with the
loading order of scripts is limited.

Richard.

Jorge

unread,
Jul 12, 2009, 11:45:05 AM7/12/09
to
Richard Cornford wrote:
> (...)

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

--
Jorge.

Richard Cornford

unread,
Jul 12, 2009, 12:23:16 PM7/12/09
to
Jorge wrote:
> Richard Cornford wrote:
>> (...)
>> 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,

Which is "exactly what Safari 4 does now"?

> that no browser did before.

None?

> And that's exactly the behaviour

Which?

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

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

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

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

Richard.

kangax

unread,
Jul 12, 2009, 1:50:43 PM7/12/09
to
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. One can also observe Firebug's "Net" panel during any web site
loading; that's probably the easiest way to observe loading behavior of
resources in Firefox (no need to install any additional tools).

The list of tools was also aimed to make it possible for anyone to
perform such testing themselves, without relying on someone else's
results/conclusions.

>
> 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.
Isn't it something that can be done once and before any resources are
being loaded, parsed, compiled and executed?

Or did I misunderstand you?

e
> all happened the script is unambiguously "loaded".
>
> 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).
>
> Monitoring HTTP traffic may tell you something about steps 1 and 2, but
> it is not the whole picture.

It is not.

But steps 1 and 2 are enough to observe cases when one resource blocks
another. From what I understand (and what Jorge is saying) is that
dynamic script insertion forces certain browsers to perform steps 1 and
2 in parallel (in context of multiple scripts). This is nothing but a
hack. A hack which could often result in scrips being *downloaded* faster.

[...]

--
kangax

It is loading more messages.
0 new messages