8

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

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

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

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

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

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

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

4

3 回答 3

3

这篇博文

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

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

  • 在 IE 中用于new Image().src预加载所有组件类型
  • 在所有其他浏览器中使用动态<object>标签

在这个例子中,我假设页面在加载下一页需要的一些组件之后预取。组件是一个 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);
    }

};

有关详细信息,请参阅帖子


编辑:查看那篇文章的评论,有人提到了这个链接,它谈到了new Image()IE 和其他浏览器中的 preload 方法的问题。这是一段摘录:

当 IE 遇到 IMG 标签时,它会创建一个图像对象并将下载请求分配给它。当数据从图像下载到达时,它被输入浏览器的图像解码器。如果您向它们提供纯文本,解码器将拒绝数据格式错误,这似乎是合理的,因为它们不可能使用这些数据。当解码器将数据拒绝为“不可能是图像”时,图像对象将中止其处理。作为该中止的一部分,如果下载尚未完成,它也被中止。

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

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

于 2013-05-17T05:37:18.843 回答
1

采用

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

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

于 2013-05-17T06:18:03.123 回答
1

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

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

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

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

(3) 胡扯到 IE,因为没有任何效果。

于 2013-05-20T15:30:31.927 回答