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


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判断变量是否为undefined的两种写法区别
Dec 04 Javascript
JQuery设置时间段下拉选择实例
Dec 30 Javascript
深入探讨javascript中的数据类型
Mar 04 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
Mar 23 Javascript
js采用concat和sort将N个数组拼接起来的方法
Jan 21 Javascript
原生js实现ajax方法(超简单)
Sep 20 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
Feb 05 Javascript
性能优化之代码优化页面加载速度
Mar 01 Javascript
jQuery EasyUI tree增加搜索功能的实现方法
Apr 27 jQuery
ES6解构赋值实例详解
Oct 31 Javascript
详解Vue路由自动注入实践
Apr 17 Javascript
element-ui和vue表单(对话框)验证提示语(残留)清除操作
Sep 11 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
在数据量大(超过10万)的情况下
2007/01/15 PHP
php函数间的参数传递(值传递/引用传递)
2013/09/23 PHP
PHP代码优化之成员变量获取速度对比
2014/02/28 PHP
JavaScript this调用规则说明
2010/03/08 Javascript
等待指定时间后自动跳转或关闭当前页面的js代码
2013/07/09 Javascript
js中substring和substr的详细介绍与用法
2013/08/29 Javascript
JS中自定义定时器让它在某一时刻执行
2014/09/02 Javascript
jQuery实现DIV层淡入淡出拖动特效的方法
2015/02/13 Javascript
input输入框鼠标焦点提示信息
2015/03/17 Javascript
JavaScript访问字符串中单个字符的两种方法
2015/07/03 Javascript
jQuery实现大转盘抽奖活动仿QQ音乐代码分享
2015/08/21 Javascript
简单谈谈JavaScript的同步与异步
2015/12/31 Javascript
jquery html动态添加的元素绑定事件详解
2016/05/24 Javascript
js基础之DOM中document对象的常用属性方法详解
2016/10/28 Javascript
layui 优化button按钮和弹出框的方法
2018/08/15 Javascript
JavaScript中callee和caller的区别与用法实例分析
2019/06/28 Javascript
浅析Vue中拆分视图层代码的5点建议
2019/08/15 Javascript
使用layui日期控件laydate对开始和结束时间进行联动控制的方法
2019/09/06 Javascript
详解vue3.0 diff算法的使用(超详细)
2020/07/01 Javascript
[00:08]DOTA2勇士令状等级奖励“天外飞星”
2019/05/24 DOTA
浅谈python中np.array的shape( ,)与( ,1)的区别
2018/06/04 Python
python检索特定内容的文本文件实例
2018/06/05 Python
python:动态路由的Flask程序代码
2019/11/22 Python
关于前端上传文件全面基础扫盲贴(入门)
2019/08/01 HTML / CSS
办公室前台岗位职责
2014/01/04 职场文书
小学国庆节活动方案
2014/02/11 职场文书
《老王》教学反思
2014/02/23 职场文书
中国梦读书活动总结
2014/07/10 职场文书
2014年话务员工作总结
2014/11/19 职场文书
员工自我工作评价
2015/03/06 职场文书
堂吉诃德读书笔记
2015/06/30 职场文书
公司管理制度范本
2015/08/03 职场文书
如何写好竞聘报告
2019/04/03 职场文书
golang在GRPC中设置client的超时时间
2021/04/27 Golang
详解GaussDB for MySQL性能优化
2021/05/18 MySQL
详解 TypeScript 枚举类型
2021/11/02 Javascript