高性能 js -- 无阻塞加载脚本
参考: <<高性能JavaScript>> Nicbolas C. Zakas 著
javascript代码的下载和执行过程会阻塞浏览器的其他进程, 比如页面的绘制, 遇到<script>标签的时候都必须停下来等待代码的下载并执行. 然后才继续处理其他部分.
无阻塞加载javascript代码的推荐方式:
// 将下面的这段加载代码放到</body>的闭合标签之前,这样确保了JS执行过程中不会阻碍页面的其他
// 内容显示, 其次第二个js文件完成下载时, 应用所需要的DOM结构已经创建完成, 并做好了交互的准备,
// 从而可以避免检测 winodw.onload事件. (注: loader.js中存放的是loadScript()的实现)
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript">
loadScript("the-rest.js",function(){
app.init();
});
</script>
也可以将loadScript 直接嵌入页面, 从而避免多产生一次HTTP请求
function loadScript(url,callback){
var script = document.createElement("script");
script.type = "text/javascript";
if(script.readyState){//for IE
script.onreadystatechange = function(){
if(script.readyState == "onload" ||
script.readyState == "complete"){
script.onreadystatechange = null; //删除事件处理器, 避免重复调用,IE自身的问题
callback();
}
}
}else{ // for other browser,<script>标签的onload事件.
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementByTagName("head")[0].appendChild(script);
}
如果需要按照顺序下载js文件,可以这样调用loadScript. 更好的方式是按顺序放到一个文件中, 避免多次HTTP请求.
// load in order, but better way is write all script in one file in order.
loadScript("file1.js",function(){
loadScript("file2.js",function(){
loadScript("file3.js",function(){
console.log("All files are loaded in order!");
});
});
});
其他无阻塞模式:
1. 使用defer: 很多浏览器目前不支持(包括chrome)
----- 当一个带有defer属性的js文件下载时, 不会阻塞浏览器的其他进程; 无论是内嵌的还是外联的defer的js脚本, 在DOM加载完成之前都不会被执行.
2. 动态脚本元素: 返回的代码通常会立即执行, 在代码包含其他接口调用时会带来问题(可以跟踪<script>节点的onload或readystatechange事件).
----- 文件在元素被添加到页面时开始下载; 无论在何时启动下载和执行过程不会阻塞页面其他进程, 推荐 append 到 head 下面.
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "file1.js";
document.getElementByTagName("head")[0].appendChild(script);
3. 使用XMLHttpRequest
----- 代码是在<script> 标签之外返回的(xhr的open), 下载之后不会立即执行. 浏览器兼容性好. 但是必须要求js文件与页面处于同一个域中.
4. 使用第三方库
----- LazyLoad: loadScript()的增强版本
<script type="text/javascript" src="lazyload-min.js"></script>
<script type="text/javascript">
LazyLoad.js(['first-file.js','second-file.js'],function(){
Application.init();
});
</script>
----- LABjs : 提供对加载过程的更精细的控制, 并试图下载尽可能多的代码
<script type="text/javascript" src="lab.js"></script>
<script type="text/javascript">
$LAB.script("first-file.js").wait() //wait在这里保证按序执行
.script('the-rest-files.js')
.wait(function(){ // 下载完成后执行的函数
Application.init();
});
</script>
高性能 js -- 无阻塞加载脚本的更多相关文章
- 探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密
下面的图片是我使用firefox和chrome浏览百度首页时候记录的http请求 下面是firefox: 下面是chrome: 在浏览百度首页前我都将浏览器的缓存全部清理掉,让这个场景最接近第一次访问 ...
- 无阻塞加载和defer、async
无阻塞加载 把js放在head里,浏览器是怎么去执行它的呢,是按顺序加载还是并行加载呢?在旧的浏览器下,都是按照先后顺序来加载的,这就保证了加载的js依赖不会发生问题.但是少部分新的浏览器已经开始允许 ...
- 无阻塞加载js,防止因js加载不了影响页面显示
浏览器加载静态资源和js的方式都是线性加载,所以一般情况可以将js放到</body>前,防止UI线程的阻塞. 而某些时候我们既希望js在整个网页的头部就加载,又担心js阻塞导致网站加载缓慢 ...
- js同步、异步、延时、无阻塞加载
一.同步加载 平常默认用的都是同步加载.如:<script src="http://yourdomain.com/script.js"></script> ...
- js实现动态加载脚本的方法实例汇总
本文实例讲述了js实现动态加载脚本的方法.分享给大家供大家参考,具体如下: 最近公司的前端地图产品需要做一下模块划分,希望用户用到哪一块的功能再加载哪一块的模块,这样可以提高用户体验. 所以到处查 ...
- 无阻塞加载外部js(动态脚本元素,XMLHttpRequest注入,LazyLoad)
动态脚本元素即在js中去创建<script>标签加载外部js并执行,这样加载的好处是文件的下载和执行过程不会阻塞页面的其他进程.通过下面两个例子对比出效果 <!DOCTYPE htm ...
- JavaScript非阻塞加载脚本
As more and more sites evolve into “Web 2.0″ apps, the amount of JavaScript increases. This is a per ...
- 高性能Javascript--脚本的无阻塞加载策略
Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中,其中一条是将JS放在底部 .原因是,事实上,大多数浏览器使用单进程处理U ...
- 【转】高性能Javascript--脚本的无阻塞加载策略
原文转自:http://blog.jobbole.com/78191/ Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中, ...
随机推荐
- rhel7配置tiger vnc详解 centos6配置安装vnc-server
参考网站:http://blog.51cto.com/xjsunjie/1963463 结合 https://blog.csdn.net/wamath/article/details/760 ...
- Sqlserver查询数据库文件大小和剩余空间
在MS Sql Server中可以能过以下的方法查询出磁盘空间的使用情况及各数据库数据文件及日志文件的大小及使用利用率: 1.查询各个磁盘分区的剩余空间:Exec master.dbo.xp_fixe ...
- 用yield 实现协程 (包子模型)
协程是一种轻量级的线程 无需线程上下级的开销, 所有的协程都在一个线程内执行 import time def consumer(name): print('%s is start to eat bao ...
- Windows窗体技术
Windows窗体技术 Winform例子下载 https://pan.baidu.com/s/1zXO8gVuFAeKQ_Tnz55A4VQ 密码:i1r6
- c++ vector, 迭代器
现代c++尽量使用vector(容器)和迭代器(相当于指针),少使用数组和指针,除非对程序执行效率有很高的要求. 容器优点,易于扩展,可通过push_back方法动态添加元素,数组不能动态添加元素. ...
- Haskell语言学习笔记(66)Aeson
Data.Aeson 安装 aeson $ cabal install aeson Installed aeson-1.2.3.0 Prelude> :m +Data.Aeson Prelude ...
- 手动安装yii2.0-redis扩展
1.点击下载:yii2.0-redis扩展 2.把下载的扩展文件放到vendor/yiisoft/下,命名为yii2-redis 3.修改vender/yiisoft/下的extensions.php ...
- AnimatorOverrideController
[AnimatorOverrideController] 有N个角色,这N个角色的状态机一样,只是动画不一样.这时候,新建一个AnimatorController,设置状态机.然后为这N个角色建立N个 ...
- ALTER数据库
alter table dbo.Sheet1$ alter column UserId int null
- input上传图片
1.通过input自身的onchange事件触发: <input id="file" type="file" accept="image/*&q ...