参考: <<高性能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 -- 无阻塞加载脚本的更多相关文章

  1. 探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密

    下面的图片是我使用firefox和chrome浏览百度首页时候记录的http请求 下面是firefox: 下面是chrome: 在浏览百度首页前我都将浏览器的缓存全部清理掉,让这个场景最接近第一次访问 ...

  2. 无阻塞加载和defer、async

    无阻塞加载 把js放在head里,浏览器是怎么去执行它的呢,是按顺序加载还是并行加载呢?在旧的浏览器下,都是按照先后顺序来加载的,这就保证了加载的js依赖不会发生问题.但是少部分新的浏览器已经开始允许 ...

  3. 无阻塞加载js,防止因js加载不了影响页面显示

    浏览器加载静态资源和js的方式都是线性加载,所以一般情况可以将js放到</body>前,防止UI线程的阻塞. 而某些时候我们既希望js在整个网页的头部就加载,又担心js阻塞导致网站加载缓慢 ...

  4. js同步、异步、延时、无阻塞加载

    一.同步加载 平常默认用的都是同步加载.如:<script src="http://yourdomain.com/script.js"></script> ...

  5. js实现动态加载脚本的方法实例汇总

      本文实例讲述了js实现动态加载脚本的方法.分享给大家供大家参考,具体如下: 最近公司的前端地图产品需要做一下模块划分,希望用户用到哪一块的功能再加载哪一块的模块,这样可以提高用户体验. 所以到处查 ...

  6. 无阻塞加载外部js(动态脚本元素,XMLHttpRequest注入,LazyLoad)

    动态脚本元素即在js中去创建<script>标签加载外部js并执行,这样加载的好处是文件的下载和执行过程不会阻塞页面的其他进程.通过下面两个例子对比出效果 <!DOCTYPE htm ...

  7. JavaScript非阻塞加载脚本

    As more and more sites evolve into “Web 2.0″ apps, the amount of JavaScript increases. This is a per ...

  8. 高性能Javascript--脚本的无阻塞加载策略

    Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中,其中一条是将JS放在底部 .原因是,事实上,大多数浏览器使用单进程处理U ...

  9. 【转】高性能Javascript--脚本的无阻塞加载策略

    原文转自:http://blog.jobbole.com/78191/ Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中, ...

随机推荐

  1. HTML5 浏览器接收的常用 content-type

    <1> 常见的设置方法 response.setHeader("content-type", 'text/html'); <2> 浏览器接收的常用 cont ...

  2. Windows 域用户

    Windows 2000 组及说明 分类: Windows 2000 的组分为Security 和 Distribution 两种. Security 类型是Windows 2000 唯一用于赋予权限 ...

  3. python中index()、find()方法

    index() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,该方法与 python find()方法一样,只不过如果st ...

  4. Java多线程之使用ATM与柜台对同一账户取钱

    钱数要设置成静态的变量,两种取钱方式操作的是同一个银行账户! 废话不多说,直接上代码.注释写的都很详细!!! package com.thread.multi2; public class Bank ...

  5. FileOperator 文件(夹)操作类

    public class FileOperator { /** * 复制文件目录 * @param srcDir 要复制的源目录 eg:/mnt/sdcard/DB * @param destDir ...

  6. Haskell语言学习笔记(59)Bitraversable

    Bitraversable class (Bifunctor t, Bifoldable t) => Bitraversable t where bitraverse :: Applicativ ...

  7. 初始化centoS 相关

    install aspnetcoremodule for iis https://docs.microsoft.com/en-us/aspnet/core/publishing/iis?tabs=as ...

  8. nstall neovim on Ubuntu 16.04

    https://neovim.io/ To install NeoVim on Ubuntu, run 1 2 3 sudo add-apt-repository ppa:neovim-ppa/sta ...

  9. 使用JS伪造Post请求

    [使用JS伪造Post请求] 提到伪造Post请求,首先想到的是构造HTTP包.但实际上有一种更简单的方法,构造HTML FORM表单,使用js进行提交.如下:

  10. frm和ibd恢复sql文件的操作

    情况:有mysql中data文件(仅仅一个数据库) 操作:frm和ibd恢复sql文件的操作 1.创建相同名字的库xxx 2.把ibdata1替换成原来的 3.把数据库xxx内内容全部替换为原来的 完 ...