最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Preload JS, but don't run it - Stack Overflow

programmeradmin3浏览0评论

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

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

Share Improve this question asked May 17, 2013 at 5:28 user2143356user2143356 5,60719 gold badges55 silver badges96 bronze badges 3
  • I suspect there is no "cleaner" solution. Good question. Nice hack. – Chris Wesseling Commented May 17, 2013 at 5:35
  • 3 Can you just wrap your code in a function declaration that you can call when its needed and include it with a <script> tag? – Jamund Ferguson Commented May 17, 2013 at 5:40
  • Why is ajax overkill? Yes it requires more code but is actually at least the same overhead as the Image() trick. Ajax may even be a bit faster because it doesn't trigger the browser's image decoding routines. – slebetman Commented May 20, 2013 at 7:42
Add a ment  | 

3 Answers 3

Reset to default 3

From this blog post:

Preloading ponents 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) es 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 ponent types
  • in all other browsers use a dynamic <object> tag

In this example I assume the page prefetches after onload some ponents that will be needed by the next page. The ponents 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./pagr2/<?php echo $id; ?>.sleep.expires.png',
            'http://tools.w3clubs./pagr2/<?php echo $id; ?>.sleep.expires.js',
            'http://tools.w3clubs./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 ments 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 pleted, it too is aborted.

This explains the behavior mentioned by the OP in the ment 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./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 (e.g. 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.

发布评论

评论列表(0)

  1. 暂无评论