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


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 相关文章推荐
用js实现预览待上传的本地图片
Mar 15 Javascript
JavaScript关于select的相关操作说明
Jan 13 Javascript
AngularJS应用开发思维之依赖注入3
Aug 19 Javascript
利用Jquery队列实现根据输入数量显示的动画
Sep 01 Javascript
你真的了解BOM中的history对象吗
Feb 13 Javascript
Angular 容器部署的方法
Apr 17 Javascript
vue 刷新之后 嵌套路由不变 重新渲染页面的方法
Sep 13 Javascript
vue-rx的初步使用教程
Sep 21 Javascript
JS 遍历 json 和 JQuery 遍历json操作完整示例
Nov 11 jQuery
javascript实现视频弹幕效果(两个版本)
Nov 28 Javascript
vue实现微信浏览器左上角返回按钮拦截功能
Jan 18 Javascript
vue 把二维或多维数组转一维数组
Apr 24 Vue.js
善用事件代理,警惕闭包的性能陷阱。
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使用正则表达式进行字符串搜索的方法
2015/03/23 PHP
老生常谈PHP 文件写入和读取(必看篇)
2017/05/22 PHP
Laravel 默认邮箱登录改成用户名登录的实现方法
2019/08/12 PHP
Mozilla 表达式 __noSuchMethod__
2009/04/05 Javascript
删除Javascript Object中间的key
2014/11/18 Javascript
jquery事件preventDefault()方法用法实例
2015/01/16 Javascript
JavaScript计划任务后台运行的方法
2015/12/18 Javascript
Bootstrap Modal对话框如何在关闭时触发事件
2016/12/02 Javascript
详解Vue2.X的路由管理记录之 钩子函数(切割流水线)
2017/05/02 Javascript
使用vue-route 的 beforeEach 实现导航守卫(路由跳转前验证登录)功能
2018/03/22 Javascript
使用vue-cli打包过程中的步骤以及问题的解决
2018/05/08 Javascript
React Router V4使用指南(精讲)
2018/09/17 Javascript
Echarts动态加载多条折线图的实现代码
2019/05/24 Javascript
Vue CLI项目 axios模块前后端交互的使用(类似ajax提交)
2019/09/01 Javascript
vue-cli3跨域配置的简单方法
2019/09/06 Javascript
Python脚本实现下载合并SAE日志
2015/02/10 Python
在Python 3中实现类型检查器的简单方法
2015/07/03 Python
Python 实现数据结构中的的栈队列
2019/05/16 Python
python实现将一维列表转换为多维列表(numpy+reshape)
2019/11/29 Python
解决selenium+Headless Chrome实现不弹出浏览器自动化登录的问题
2021/01/09 Python
html5需遵循的6个设计原则
2016/04/27 HTML / CSS
微软俄罗斯官方网站:Microsoft俄罗斯
2016/09/18 全球购物
Reebok俄罗斯官方网上商店:购买锐步运动服装和鞋子
2016/09/26 全球购物
介绍一下HTTP、HTTPS和SSL
2012/12/16 面试题
27个经典Linux面试题及答案,你知道几个?
2013/01/10 面试题
Java中采用什么结构来捕获、处理异常?各子句的顺序、功能如何
2013/10/07 面试题
竞选部门副经理的自荐书范文
2014/02/11 职场文书
小学生学雷锋演讲稿
2014/04/25 职场文书
2014报到证办理个人委托书
2014/10/08 职场文书
税务干部个人整改措施思想汇报
2014/10/10 职场文书
学校党的群众路线教育实践活动整改措施
2014/10/25 职场文书
大学生见习报告范文
2014/11/03 职场文书
五年级小学生评语
2014/12/26 职场文书
职场领导同事生日简短祝福语
2019/08/06 职场文书
Redis字典实现、Hash键冲突及渐进式rehash详解
2021/09/04 Redis
如何利用python实现Simhash算法
2022/06/28 Python