简体   繁体   中英

Preload JS, but don't run it

I want to preload a large JS file after a page has loaded, so that when I link to that JS file on the required page it is already downloaded and cached.

I'm basically doing this at the moment, and it works, but of course it's not the right way:

preload_js = new Image();
preload_js = "http://domain.com/files/file.js";

This seems such a quick and simple method, no Ajax needed etc. and it works great.

What's the proper way to do this? Surely not with Ajax as that seems overkill for this.

I know there's lots of methods for loading JS but they all seem to actually run the code after the script has loaded, which I don't want.

I don't want to use jQuery (or any library), it must be plain JS. Thanks for any help.

From this blog post :

Preloading components in advance is good for performance. There are several ways to do it. But even the cleanest solution (open up an iframe and go crazy there) comes at a price - the price of the iframe and the price of parsing and executing the preloaded CSS and JavaScript. There's also a relatively high risk of potential JavaScript errors if the script you preload assumes it's loaded in a page different than the one that preloads.

After a bit of trial and lot of error I think I came up with something that could work cross-browser:

  • in IE use new Image().src to preload all component types
  • in all other browsers use a dynamic <object> tag

In this example I assume the page prefetches after onload some components that will be needed by the next page. The components are a CSS, a JS and a PNG (sprite).

 window.onload = function () { var i = 0, max = 0, o = null, // list of stuff to preload preload = [ 'http://tools.w3clubs.com/pagr2/<?php echo $id; ?>.sleep.expires.png', 'http://tools.w3clubs.com/pagr2/<?php echo $id; ?>.sleep.expires.js', 'http://tools.w3clubs.com/pagr2/<?php echo $id; ?>.sleep.expires.css' ], isIE = navigator.appName.indexOf('Microsoft') === 0; for (i = 0, max = preload.length; i < max; i += 1) { if (isIE) { new Image().src = preload[i]; continue; } o = document.createElement('object'); o.data = preload[i]; // IE stuff, otherwise 0x0 is OK //o.width = 1; //o.height = 1; //o.style.visibility = "hidden"; //o.type = "text/plain"; // IE o.width = 0; o.height = 0; // only FF appends to the head // all others require body document.body.appendChild(o); } }; 

See the post for more details.


EDIT: Looking at the comments on that post, someone mentions this link , which talks about the problems with the new Image() preload method in IE and other browsers. Here's an excerpt:

When IE encounters an IMG tag, it creates an image object and assigns the download request to it. As data arrives from the image download, it's fed into the browser's image decoders. The decoders will reject data as malformed if you feed them plaintext, which seems reasonable, since they can't possibly make use of such data. When the decoders reject the data as "Not possibly an image," the image object will abort its processing. As a part of that abort, if the download has not yet completed, it too is aborted.

This explains the behavior mentioned by the OP in the comment below (IE9 only downloading 4KB of the file).

It seems like your only reliable cross-browser option may be to use Ajax...

USE

window.document.onload =function(){
preload_js = "http://domain.com/files/file.js";
}

window.document.onload make sure the java script will not run until you dom is ready

Considering the cross domain issues with Ajax, especially since there really is no way to load a file on a server you have no control over (eg Google CDN hosting jQuery), this is my solution:

(1) Use the document.createElement('object') part in Simon M's solution for Firefox as that works great.

(2) Use the new Image.src thing for every other browser. Opera, Safari and Chrome love it. Also, I mentioned earlier that Mobile Safari doesn't work. Well it does, but for some reason takes 100ms verifying something (it is properly cached and it isn't just returning a 304 not modified). I can live with 100ms.

I've not tested other mobile browsers.

(3) Bollocks to IE as nothing works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM