预加载JS,但不要运行它

时间:2013-05-17 05:28:53

标签: javascript

我想在页面加载后预加载一个大的JS文件,这样当我链接到所需页面上的那个JS文件时,它已经被下载并缓存了。

我现在基本上都是这样做的,但它确实有效,但当然这不是正确的方法:

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

这似乎是一种快速而简单的方法,不需要Ajax等,而且效果很好。

这样做的正确方法是什么?当然不是Ajax,因为这似乎有点矫枉过正。

我知道有很多方法可以加载JS,但是在脚本加载之后它们似乎都运行了代码,这是我不想要的。

我不想使用jQuery(或任何库),它必须是普通的JS。谢谢你的帮助。

3 个答案:

答案 0 :(得分:3)

来自this blog post

  

提前预加载组件有利于提高性能。有   有几种方法可以做到。但即使是最干净的解决方案(打开一个   iframe,并在那里疯狂)来了一个价格 - iframe的价格   以及解析和执行预加载的CSS和的价格   JavaScript的。潜在风险也相对较高   如果您预加载的脚本假定它已加载到的JavaScript中,则会出现JavaScript错误   页面与预装的页面不同。

     

经过一些试验和很多错误,我想我想出了一些东西   这可以跨浏览器工作:

     
      IE中的
  • 使用new Image().src预加载所有组件类型
  •   所有其他浏览器中的
  • 都使用动态<object>代码
  •   
     

在这个例子中,我假设在onload之后页面预取了一些   下一页将需要的组件。组件是a   CSS,JS和PNG(精灵)。

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);
    }

};

有关详细信息,请参阅the post


编辑:查看该帖子的评论,有人提及this link,其中讨论了IE和其他浏览器中new Image()预加载方法的问题。这是一段摘录:

  

当IE遇到IMG标记时,它会创建一个图像对象并进行分配   下载请求。当数据从图像下载到达时,   它被送入浏览器的图像解码器。解码器将拒绝   如果您提供纯文本格式错误,这似乎是合理的,   因为他们不可能利用这些数据。当解码器   拒绝数据为“不可能是图像”,图像对象将   中止其处理。作为该中止的一部分,如果下载没有   虽然已经完成,但它也已中止。

这解释了OP在下面的评论中提到的行为(IE9仅下载了4KB的文件)。

似乎您唯一可靠的跨浏览器选项可能是使用Ajax ...

答案 1 :(得分:1)

使用

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

window.document.onload确保在dom准备好之前java脚本不会运行

答案 2 :(得分:1)

考虑到Ajax的跨域问题,特别是因为实际上没有办法在服务器上加载你无法控制的文件(例如Google CDN托管jQuery),这是我的解决方案:

(1)在Simon M的Firefox解决方案中使用document.createElement('object')部分,因为它很有效。

(2)对每个其他浏览器使用新的Image.src。 Opera,Safari和Chrome都喜欢它。另外,我之前提到Mobile Safari不起作用。它确实如此,但由于某种原因需要100毫秒来验证某些东西(它被正确缓存并且它不仅仅返回304未修改)。我可以忍受100毫秒。

我没有测试过其他移动浏览器。

(3)Bollocks到IE无效。