Caching Scripts With no-cache headers

39 views
Skip to first unread message

Server Herder

unread,
Dec 16, 2010, 3:54:28 PM12/16/10
to ControlJS
The use of an OBJECT or IMG element to trigger caching of remote URL's
is a good idea; however, it suffers from one problem which is
undetectable by the library and has the potential to considerably
increase load times: Scripts that send no-cache headers will be
requested twice. Scripts without cache-control or expires headers can
be requested multiple times if the heuristic cache detection algorithm
triggers it. Moreover, hard-reloading a page may cause this to happen
regardless of cache headers (although I've not tested this). While
the benefits of pre-fetching may outweigh this concern (most un-
cacheable scripts are embedded using document.write() anyway and hard
reloads should be rare), it would seem wise to address this.

Internet Explorer provides the pre-fetching capabilities implemented
in ControlJS out-of-the-box through it's readyState property and
corresponding readystatechange event. Here's an example page that
shows how it works. This page implements a loadscripts() function
that asynchronously downloads an array of URL's but then executes them
in parallel. It does this by creating only one script element, relies
on the fact that IE will begin resource retrieval immediately upon
assignment of the src and identifies when the script has finished by
testing for the readyState property for a value of "loaded".

http://digital-fulcrum.com/executionorder/

It would require ControlJS maintain a reference to the actual script
object as opposed to just the URL so it would require some non-trivial
re-factoring; however, it would seem to be a worthwhile endeavour.

Steve Souders

unread,
Dec 16, 2010, 5:51:03 PM12/16/10
to cont...@googlegroups.com, Server Herder
Hi, Server Herder.

I understand the issue, but don't understand the code.

I see you're creating SCRIPT elements and setting the
.onreadystatechange and .src. But I don't understand how executeScripts
fits in. Isn't the script executed without any intervention? And in
fact, how would you *stop* execution with this approach?

-Steve

Will Alexander

unread,
Dec 16, 2010, 7:10:10 PM12/16/10
to ControlJS
It may help to draw a comparison with an an IMG element. When you set
the "src" attribute on an IMG it is immediately fetched. However,
it's not going to be displayed until it's inserted into the DOM.

IE's behavior with SCRIPT elements is (surprisingly) consistent. Just
like an IMG that's not in the DOM isn't going to be displayed. a
SCRIPT that's not in the DOM doesn't **execute**.

It fetches the URL as soon as we assign the src without the need to
add it to the DOM. IE will still update the readyState property to
"loaded" and fire the readystatechange once it finishes downloading.
At any point we can choose to execute the script simply by inserting
it (execution will actually occur *synchronously*)

Here's how it would look for a single script:

var script= document.createElement("script");
script.onreadystatechange= handler;
/* IE downloads NOW */
script.src= "......";

function handler(){
if(this.readyState == "loaded"){
/*
The script has downloaded but not executed.
We trigger execution by adding it to the DOM, but we
don't have to
*/
document.body.appendChild(this);
}else if (this.readyState == "complete") {
/* The script has executed. */

Steve Souders

unread,
Dec 16, 2010, 7:21:35 PM12/16/10
to cont...@googlegroups.com, Will Alexander
I didn't know that. Can you submit a bug summarizing your proposal?

http://code.google.com/p/controljs/issues/list

Thanks.

-Steve

Will Alexander

unread,
Dec 16, 2010, 8:22:40 PM12/16/10
to ControlJS
Patch is attached to this issue.
http://code.google.com/p/controljs/issues/detail?id=10

My hope is the IE behavior is codified in the HTML 5 standard. I
believe it is considerably more flexible than simply relying on a
global synchronized queue and mitigates caching problems.
Compatibility is also almost a non-issue since it's implemented in IE
4+. It's also very helpful to have a readyState property which can
provide hints if the onload event is missed.

http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
Reply all
Reply to author
Forward
0 new messages