Script 元素的异步加载属性

标签: 开发 async firefox js script | 发表时间:2010-03-07 18:15 | 作者:lifesinger jungledrum
出处:http://lifesinger.org/blog

进入正题之前,先考大家一个问题:defer 属性现在有哪些浏览器支持?

喜悦

除了 defer 属性,script 还新增了一个 async 属性,请看 MDC

async Requires Gecko 1.9.2
This Boolean attribute is set to indicate that the browser should, if possible, execute the script asynchronously. If the script cannot be executed asynchronously, or the browser doesn’t support this attribute, the script is executed synchronously (and loading the content blocks until the script finishes running).

理想情况下,利用 async 属性,脚本异步加载将变得非常简单:
async-test.js:

var g = 1;

async-test-1.html:

<script src="async-test.js" async="true"></script>
<script>
    alert(typeof g); // Firefox 3.6 弹出 undefined
</script>

测试页面:async-test-1.html
目前只有 Firefox 3.6 支持 async 属性,希望其它浏览器能迅速跟进。

悲哀

Firefox 3.6 的尝试和探索精神令人钦佩。但是,在引入这个新特性时,也导致了传统异步加载方式的失效:

<script>
    (function(d) {
        var a = d.createElement('script');
        a.src = 'async-test.js';
        d.getElementsByTagName('head')[0].appendChild(a);
    })(document);
</script>
<script>
    alert(typeof g); // 预期结果是 undefined, Firefox 3.6 弹出 number
</script>

测试页面:async-test-2.html
真糟糕!类似问题,还有 Steve Souders 前不久发现的 document.write 在 Firefox 3.6 下的阻塞行为

分析

用 Firebug 可以看到,在 Firefox 3.6 中,script 元素 async 属性的默认值是 false. 换言之,script 元素默认是同步加载的。可以推测,Firefox 3.6 在增加 async 这个属性时,很可能忽略了用 createElement(’script’) 和 document.write(‘<script…’) 等方式创建的 script 元素,async 的属性值应该从默认值 false 调整为 true. 正是这个疏忽,导致了传统加载异步脚本的方式在 Firefox 3.6 中失效。对于 YUI3 和很多站点来说,这实在是太糟糕了。

知道了问题本因,可以得到目前异步加载脚本最安全的方式如下:

<script>
    (function(d) {
        var a = d.createElement('script');
        a.async = true;
        a.src = 'async-test.js';
        d.getElementsByTagName('head')[0].appendChild(a);
    })(document);
</script>

测试页面:async-test-3.html

注意1:所有测试结果,均在无缓存的情况下得出。
注意2:async-test-2.html 和 async-test-3.html 在 Opera 10.10 中弹出值非预期,原因未深究,有兴趣者可以进一步挖掘。

感慨

Google 在 ga 的部署脚本 中已经使用上了 async 属性:

<script type="text/javascript">
    (function() {
      var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
      ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
      (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
    })();
  </script>

最后

再考大家一题,在 Firefox 3.6 下,下面的代码,alert 出什么:

<script src="async-test.js" async="false"></script>
<script>
    alert(typeof g); // ?
</script>

相关 [script 元素 异步] 推荐:

Script 元素的异步加载属性

- jungledrum - 岁月如歌
进入正题之前,先考大家一个问题:defer 属性现在有哪些浏览器支持. 除了 defer 属性,script 还新增了一个 async 属性,请看 MDC:. If the script cannot be executed asynchronously, or the browser doesn’t support this attribute, the script is executed synchronously (and loading the content blocks until the script finishes running).

script的defer和async

- - 携程UED
我们常用的script标签,有两个和性能、js文件下载执行相关的属性:defer和async. defer的含义【摘自 https://developer.mozilla.org/En/HTML/Element/Script】. This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed..

「学习笔记-Linux」学习Shell Script

- - CSDN博客系统运维推荐文章
学习Shell Script. 1 什么是Shell Scipt. 2.2 例2 按日期建立相似名字的文件. 3.2.4 整数,字符串,多重条件判断. 4 Shell Script 参数. 5.2 if else 结构. 8 shell script的追踪与Debug. 1 什么是Shell Scipt.

前端优化三续:用script存放html代码来减少DOM节点数

- - 博客园_旁观者
前端优化三续:美团的实践——用script存放html代码来减少DOM节点数. 玉伯在《 淘宝详情页的 BigRender 优化与存放大块 HTML 内容的最佳方式》中提到,. 与前面  textarea 存放 html 代码 一样,你也可以 用 script 来存放,目的都是减少 DOM 节点数.

逃走的元素

- Zoe - 玩意儿
艺术家将寻常东东让它们部分元素像是往外逃走的样子,营造一种3D错觉感,很创意深刻,这里有他更多的作品,点此访问. 本文原始链接:http://www.cngadget.cn/tao-zou-de-yuan-su.html.

linux异步IO浅析

- Sepher - kouu&#39;s home
知道异步IO已经很久了,但是直到最近,才真正用它来解决一下实际问题(在一个CPU密集型的应用中,有一些需要处理的数据可能放在磁盘上. 预先知道这些数据的位置,所以预先发起异步IO读请求. 等到真正需要用到这些数据的时候,再等待异步IO完成. 使用了异步IO,在发起IO请求到实际使用数据这段时间内,程序还可以继续做其他事情).

Android handler异步更新

- - 博客园_首页
private static final int MSG_SUCCESS = 0;// 获取图片成功的标识. private static final int MSG_FAILURE = 1;// 获取图片失败的标识. mImageView.setImageBitmap((Bitmap) msg.obj);// imageview显示从网络获取到的logo.

Android异步接口测试

- - 百度质量部 | 软件测试 | 测试技术 | 百度测试
    基于Android的C/S移动应用中访问后端数据的场景是非常多的,异步接口测试主要是在单元测试完成的基础上检查接口级访问是否正确,主要保证对外请求的组装与发送是否符合后端的约定. 现在项目的异步接口访问都遵循一个特定的访问模式:前台的Activity获取到触发事件后将接受到的参数传给一个异步任务,这些任务大都是AsyncTask的实现——即启动一个新的线程访问后台接口数据,完毕后调用回调函数更新UI展示,示意图如下:.

异步上传文件

- - Web前端 - ITeye博客
通过iframe来实现无刷新的的文件上传,其实是有刷新的,只是在iframe里面隐藏了而已. form里面的target要与iframe里面的id的值相等,指示是form相应了post事件,也就是post时间相应的时候刷新的是iframe而不是整个页面. 用户名:
上传头像:

java异步计算Future

- - 互联网 - ITeye博客
从jdk1.5开始我们可以利用Future来跟踪异步计算的结果. 在此之前主线程要想获得工作线程(异步计算线程)的结果是比较麻烦的事情,需要我们进行特殊的程序结构设计,比较繁琐而且容易出错. 有了Future我们就可以设计出比较优雅的异步计算程序结构模型:根据分而治之的思想,我们可以把异步计算的线程按照职责分为3类:.