无阻塞加载脚本分析[全]


Posted in Javascript onJanuary 20, 2011

由于浏览器是单线程的,因此脚本在载的时候会阻塞下载其它资源;虽然在现在浏览器已经有所改善,但仍然有待改进。
很显然,脚本必须按顺序执行,但没有必要按顺序下载,解决方法:
1。内嵌JS
通常由于页面大小和缓存能带来更多好处,因此外部文件引入JS更好一些;
在少数情况下,比如首页、少量JS情况下尚可接受。
2。XHR Eval
通过XMLHttpRequest从服务器端获取脚本。
主要缺陷是,通过XHR获取的脚本必须部署在和主页面相同的域中。

Ajax.get("test.js", function (xhr) { 
eval(xhr.responseText); 
});

3。XHR注入
使用XHR获取脚本并创建script标签。
同样,通过XHR获取的脚本必须部署在和主页面相同的域中。
Ajax.get('test.js', function (xhr) { 
injectscript(xhr.responseText); 
}); 
function injectscript(scriptText) { 
var s = document.createElement('script'); 
s.text = scriptText; 
document.getElementsByTagName('head')[0].appendChild(s); 
}

4。Script in Iframe
将需要的脚本放入到一个页面中,然后通过iframe来加载该页面。
缺点是iframe本身的开销比较大,另外浏览器安全机制不允许iframe中的js访问跨域的父页面,反之亦然。
5。Script DOM Element
JS动态创建script DOM元素并设置其src属性。
var scriptElem = document.createElement('script'); 
scriptElem.src = 'http://domain.com/test.js'; 
document.ge('head')[0].appendChild(scriptElem);

6。Script Defer
给script标签添加defer属性。
缺点是只有IE和一些新浏览器支持。
<script defer src='test.js'></script>

7。document.write Script Tag
使用document.write把HTML标签script写入页面。
缺点是只有在IE中是并行加载脚本的。
document.write("<script type='text/javascript' src='test.js'><\/script>");

有一个大家不曾广泛讨论的不同点是对于浏览器忙碌状态的影响,包括浏览器的状态栏、进度条、Tab图标以及鼠标。
当你加载多个彼此间有依赖关系的脚本时,还需要一种能够保证执行顺序的技术。
技术    并行下载    可以跨域    存在Script标签    忙碌指示  顺序保证  大小 (bytes)
XHR Eval IE, FF, Saf, Chr, Op no no Saf, Chr - ~500
XHR Injection IE, FF, Saf, Chr, Op no yes Saf, Chr - ~500
Script in Iframe IE, FF, Saf, Chr, Op no no IE, FF, Saf, Chr - ~50
Script DOM Element IE, FF, Saf, Chr, Op yes yes FF, Saf, Chr FF, Op ~200
Script Defer IE, Saf4, Chr2, FF3.1 yes yes IE, FF, Saf, Chr, Op IE, FF, Saf, Chr, Op ~50
document.write Script Tag IE, Saf4, Chr2, Op yes yes IE, FF, Saf, Chr, Op IE, FF, Saf, Chr, Op ~100
在大多数情况下,Script DOM Element是一个好的选择。这种方式适用于所有的浏览器,而且没有跨域的限制,实现起来也非常的简单和易于理解。唯一的缺点是不能保证各个脚本的执行顺序。如果需要加载多个有依赖关系的脚本,应该将这些脚本拼成一个来保证其按需要的顺序执行,或者使用别的技术。
目前异步加载时保持执行顺序的方法有下面几种,由于篇幅原因,暂不详细描述。
单个脚本
1、Hardcoded Callback
2、Window Onload
3、Timer
4、Script Onload
5、Degrading Script Tags
多个脚本
1、Managed XHR
2、DOM Element and Doc Write
本文参考《高性能网站建设进阶指南》
Javascript 相关文章推荐
15个款优秀的 jQuery 图片特效插件推荐
Nov 21 Javascript
CSS(js)限制页面显示的文本字符长度
Dec 27 Javascript
淘宝网提供的国内NPM镜像简介和使用方法
Apr 17 Javascript
jQuery带时间的日期控件代码分享
Aug 26 Javascript
自己封装的一个简单的倒计时功能实例
Nov 23 Javascript
Vue2.x中的Render函数详解
May 30 Javascript
使用JavaScript中的lodash编写双色球效果
Jun 24 Javascript
jQuery的Ajax接收java返回数据方法
Aug 11 jQuery
深入浅析Node环境和浏览器的区别
Aug 14 Javascript
JavaScript arguments.callee作用及替换方案详解
Sep 02 Javascript
vue项目中播放rtmp视频文件流的方法
Sep 17 Javascript
Vue实现简单的留言板
Oct 23 Javascript
善用事件代理,警惕闭包的性能陷阱。
Jan 20 #Javascript
jqeury eval将字符串转换json的方法
Jan 20 #Javascript
通过Jquery遍历Json的两种数据结构的实现代码
Jan 19 #Javascript
JQuery动态给table添加、删除行 改进版
Jan 19 #Javascript
jQuery 1.5最新版本的改进细节分析
Jan 19 #Javascript
基于Jquery与WebMethod投票功能实现代码
Jan 19 #Javascript
jQuery '行 4954 错误: 不支持该属性或方法' 的问题解决方法
Jan 19 #Javascript
You might like
使用bcompiler对PHP文件进行加密的代码
2010/08/29 PHP
php设置页面超时时间解决方法
2015/09/22 PHP
Zend Framework教程之Application用法实例详解
2016/03/14 PHP
ThinkPHP模板Volist标签嵌套循环输出多维数组的方法
2016/03/23 PHP
用JavaScript实现动画效果的方法
2013/07/20 Javascript
javascript获取下拉列表框当中的文本值示例代码
2013/07/31 Javascript
javascript强大的日期函数代码分享
2013/09/04 Javascript
Jquery 过滤器(first,last,not,even,odd)的使用
2014/01/22 Javascript
实例详解angularjs和ajax的结合使用
2015/10/22 Javascript
JavaScript深度复制(deep clone)的实现方法
2016/02/19 Javascript
Node.js模块封装及使用方法
2016/03/06 Javascript
jQuery Tags Input Plugin(添加/删除标签插件)详解
2016/06/20 Javascript
理解javascript中的闭包
2017/01/11 Javascript
Android中Okhttp3实现上传多张图片同时传递参数
2017/02/18 Javascript
Element Input组件分析小结
2018/10/11 Javascript
新手入门js闭包学习过程解析
2019/10/08 Javascript
Vue Router的手写实现方法实现
2020/03/02 Javascript
在antd Table中插入可编辑的单元格实例
2020/10/28 Javascript
react中hook介绍以及使用教程
2020/12/11 Javascript
[46:04]Liquid vs VP Supermajor决赛 BO 第四场 6.10
2018/07/05 DOTA
python实现在无须过多援引的情况下创建字典的方法
2014/09/25 Python
Python各类图像库的图片读写方式总结(推荐)
2018/02/23 Python
Centos7 Python3下安装scrapy的详细步骤
2018/03/15 Python
django之静态文件 django 2.0 在网页中显示图片的例子
2019/07/28 Python
python批量替换文件名中的共同字符实例
2020/03/05 Python
Python之关于类变量的两种赋值区别详解
2020/03/12 Python
金属材料工程个人求职的自我评价
2013/12/04 职场文书
高中毕业生登记表自我鉴定范文
2014/03/18 职场文书
超市仓管员岗位职责范本
2014/09/18 职场文书
工厂见习报告范文
2014/10/31 职场文书
2014年标准化工作总结
2014/12/17 职场文书
审查起诉阶段律师意见书
2015/05/19 职场文书
最新的离婚协议书范本!
2019/07/02 职场文书
实习报告范文之电话客服岗位
2019/07/26 职场文书
OpenCV-Python实现怀旧滤镜与连环画滤镜
2021/06/09 Python
springboot项目以jar包运行的操作方法
2021/06/30 Java/Android