【问题标题】:load scripts asynchronosly and have a fallback异步加载脚本并有一个回退
【发布时间】:2012-04-20 06:05:10
【问题描述】:

我的目标是在浏览器支持延迟或异步时异步加载脚本。
如果浏览器都不支持,我不关心异步加载(不是我的坏)。
我想确保仅在满足其先决条件时才执行任何脚本,例如已加载 jQuery。 我想在加载其他脚本的同时加载我的脚本(仅当浏览器支持延迟或异步时)。

我想仅使用浏览器的 API 来执行此操作。我不希望浏览器加载任何可靠(或不)为我执行此操作的脚本,无论它们多么小。

这必须适用于 IE8+、Gecko v.1.9.1+(例如 firefox 3.5.* 或 firefox 9.0+)、webkit(例如 chrome)、presto(例如 Opera)。对于我没有提到版本的那些,我是指最新的稳定版本。

如果可能的话,我不想要任何不简单的脚本。我只需要一些简单的东西来完成这项工作。这意味着:
如果可能的话,我不希望 AJAX 调用或带有某些方法的花哨对象之类的东西来做一些我在其他页面中看到的变通方法。这些是在不支持异步或延迟的浏览器中强制异步加载脚本

我再说一遍:我不需要任何花哨的东西来使脚本异步。如果浏览器不支持延迟或异步,我不在乎。我只关心加载脚本,以便在满足其先决条件后执行每个部分,并使用异步或延迟如果浏览器支持它

【问题讨论】:

  • 祝你重新发明轮子好运
  • 你这么说,那只是表示你不知道我在这里要求什么。我不想要轮子。我只是想确保一切都按正确的顺序运行。
  • 主要原因是因为我不想挂起只是为了下载当浏览器支持延迟或异步时解决挂起的脚本

标签: javascript deferred-execution


【解决方案1】:

首先,使用jQuery 之类的库可以让整个过程变得无比轻松,并且跨浏览器更加可靠。它可能会增加页面的下载大小(增加很小的量),但通过有效的脚本加载/执行所获得的速度几乎总是会超过这一点。

关于脚本异步和延迟属性:

  1. async="async":在脚本标签上 IE8/9 根本不支持,脚本立即执行(根据您的问题可以)。

  2. defer="defer":在脚本标记将在所有内容之后按照延迟脚本在 HTML 中出现的顺序开始加载,在 DOM 就绪之前。但是,在 Firefox 上,脚本通常会在 dom 准备好之后执行。这种差异使得 defer 在 dom 就绪后确保在执行函数之前加载脚本的方法不可靠。

不使用jQuery时的一般准则:

  1. 如果脚本具有下游依赖项,您必须将其作为标准脚本标签放在正文标签的末尾,并在文档准备好后执行所有内联标签。否则,无法保证脚本将在执行依赖项之前执行。 Firefox 是这里的主要问题,即使 DOM 准备好,“延迟”脚本也可能没有完成。

  2. 如果脚本没有下游依赖项,则将其放在主体标签的末尾,并在脚本标签上使用 async="async" 属性。 IE会立即渲染,其他人收到后会渲染。

使用jQuery 时的一般准则:

  1. 在您的<head> 中仅放置 jQuery。

  2. $.getScript() 执行所有其他脚本。

  3. 如果脚本需要尽快执行(例如分析),请在正文顶部使用$.getScript(这将是一个非阻塞请求,但会在客户端收到文件后立即处理)。

  4. 如果脚本可以等到 DOM 准备好,请将 $.getScript() 调用包装在 $(function() {});

  5. 如果一个脚本有很多下游依赖,让每个都将自己注册到特定脚本的回调函数中。

  $(function() { 
    $.getScript("script.js", function() {
      for(var i = 0; i < myCallbacks.length;i++) {
        myCallbacks[i]();
      }
    });
  });

【讨论】:

  • 令人惊讶的是,jQuery 的 getScript() 竟然失败了。尽管它能够获取脚本,但在当前最常用的浏览器(FF 3.6、FF11、IE8、IE9...)中,它比简单地将标签放在页面底部要慢。此外,getScript() 依赖于缓存,可能会在浏览器中关闭(如果发生这种情况,则会发生 2 次下载)
  • 我没有看到任何证据表明脚本被加载了两次,请查看此测试小提琴jsfiddle.net/nKsGP,我将网络服务器设置为应请求休眠 5 秒(以模拟慢速脚本)。如果它加载两次,则需要 10 秒,它不会。此外,我不太明白它怎么会“更慢”......加载脚本正在加载脚本。在底部使用 $.getScript() 而不是普通标签的主要原因是,dom 就绪事件仍然可以触发,而不必等待所有脚本加载,如果有一次超时,那就太糟糕了。
  • 您是否关闭了缓存?如果你没有,那么你的测试就不能证明我写了什么。
  • 我确实关闭了缓存,如果你去我链接的小提琴,你可以自己测试它。我很确定您提出的批评与 head.js 相关,而不是 jQuery。来自headjs.com - This trick is used on Chrome, Safari and IE. Without caching enabled a file will be loaded twice on the initial load.
  • Analytics 根本不需要尽快加载。恰恰相反,这是一种可以在不影响用户体验的情况下最晚加载的脚本。它不会对您的统计数据产生足够的影响,不会成为问题。
猜你喜欢
  • 2012-10-01
  • 2011-12-04
  • 1970-01-01
  • 2016-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
相关资源
最近更新 更多