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


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 相关文章推荐
JavaScript Object的extend是一个常用的功能
Dec 02 Javascript
jquery简单的拖动效果实现原理及示例
Jul 26 Javascript
window.print打印指定div指定网页指定区域的方法
Aug 04 Javascript
深入理解JavaScript系列(41):设计模式之模板方法详解
Mar 04 Javascript
深入理解事件冒泡(Bubble)和事件捕捉(capture)
May 28 Javascript
AngularJS入门教程之表格实例详解
Jul 27 Javascript
layer弹出层中H5播放器全屏出错的解决方法
Feb 21 Javascript
利用Ionic2 + angular4实现一个地区选择组件
Jul 27 Javascript
React应用中使用Bootstrap的方法
Aug 15 Javascript
webstorm中vue语法的支持详解
May 09 Javascript
layui上传图片到服务器的非项目目录下的方法
Sep 26 Javascript
解决vue cli4升级sass-loader(v8)后报错问题
Jul 30 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
PHP中func_get_args(),func_get_arg(),func_num_args()的区别
2013/09/30 PHP
PHP把网页保存为word文件的三种方法
2014/04/01 PHP
基于php实现随机合并数组并排序(原排序)
2015/11/26 PHP
PHP实现ASCII码与字符串相互转换的方法
2017/04/29 PHP
jQuery 源代码显示控件 (Ajax加载方式).
2009/05/18 Javascript
validator验证控件使用代码
2010/11/23 Javascript
asp.net中System.Timers.Timer的使用方法
2013/03/20 Javascript
如何在JavaScript中实现私有属性的写类方式(一)
2013/12/04 Javascript
对js关键字命名的疑问介绍
2014/04/25 Javascript
分享10个原生JavaScript技巧
2015/04/20 Javascript
js判断手机端(Android手机还是iPhone手机)
2015/07/22 Javascript
字符串反转_JavaScript
2016/04/28 Javascript
javascript Promise简单学习使用方法小结
2016/05/17 Javascript
BootStrap表单控件之复选框checkbox和单选择按钮radio
2017/05/23 Javascript
浅谈sass在vue注意的地方
2017/08/10 Javascript
在 Angular 中使用Chart.js 和 ng2-charts的示例代码
2017/08/17 Javascript
深入理解React高阶组件
2017/09/28 Javascript
在vue中解决提示警告 for循环报错的方法
2018/09/28 Javascript
微信小程序生成分享海报方法(附带二维码生成)
2019/03/29 Javascript
JS数组push、unshift、pop、shift方法的实现与使用方法示例
2020/04/29 Javascript
python的几种开发工具介绍
2007/03/07 Python
python中list循环语句用法实例
2014/11/10 Python
黑科技 Python脚本帮你找出微信上删除你好友的人
2016/01/07 Python
插入排序_Python与PHP的实现版(推荐)
2017/05/11 Python
TF-IDF算法解析与Python实现方法详解
2017/11/16 Python
Python使用matplotlib和pandas实现的画图操作【经典示例】
2018/06/13 Python
Python流程控制 if else实现解析
2019/09/02 Python
基于spring boot 日志(logback)报错的解决方式
2020/02/20 Python
详解Pycharm出现out of memory的终极解决方法
2020/03/03 Python
python 数据库查询返回list或tuple实例
2020/05/15 Python
戴尔英国翻新电脑和电子产品:Dell UK Refurbished Computers
2019/07/30 全球购物
楼面部长岗位职责范本
2014/02/14 职场文书
聚美优品励志广告词
2014/03/14 职场文书
医生个人年度总结
2015/02/28 职场文书
学校计划生育责任书
2015/05/09 职场文书
离婚起诉书范本
2015/05/18 职场文书