javascript加载阻隔特性解决方案

大家都知道浏览器加载外部文件(css和js),都是呈阻碍式加载,试想如果外部引入文件过多,外加程序js执行时间和http请求/相应的延迟,会使页面的空白时间加长,影响用户体验。有的人可以说,可以把页面所需的css文件放入<head/>标签中,js文件放入<body/>内尾部,这样可以在页面部分显示后再加载和执行js文件,提高用户体验,确实这是一种有效的解决方案。

随之而来,将js文件放入尾部,如果文件数量小,但如果引入的文件数量挺大,就会造成页面的交互失灵,因为js文件在用户点击页面是,页面引入的js文件还没有完全加载并执行。

解决方法大概有两种方式:

(1)如果可以尽量将需引入的js文件合并为一个文件,减少浏览器对服务器的请求次数,减少延迟时间,提高js的加载和执行速度。

(2)另一个解决方案就是解决js文件加载和执行的阻塞特性(重点终于出来了),希望js文件的加载可以解决浏览器的阻塞特性:

    1.<script/>标签的defer属性

     在<script/>标签中添加defer属性可以使在<head/>中引入的js文件,在页面加载的时候不加载/执行,而是等页面加载完成后才加载执行(也就是window.onload事件促发时)。其实defer的功效和把js文件放入<body/>后的效果是一样的,但它确实现了打破浏览器的引入阻碍特性。但并不是所有浏览器都支持defer素性,除IE和FF3.1支持外,其他浏览器都将无视defer属性。

    2.实时创建<script/>标签

     实现的方式,并不是一开始把大量的js文件引入文件中,而是在需要时再引入所需的js文件。引入如下函数即可实现:


function deferLoad(url,fn){
  var script = this.element("script");
  script.type = "text/javascript";
  script.src= url;
  args = Array.prototype.slice.call(arguments,2);
  if(script.readyState){
    script.onreadystatechange = function(){
      if(script.readyState == "loaded" || script.readyState == "complete"){
        script.onreadystatechange = null;
        fu.apply(this,args);
      }  	
    };
  }else{
    script.onload = function(){
      fu.apply(this,args);	
    }; 
  }
  document.getElementsByTagName("head")[0].appendChild(script);
};
上面封装的deferLoad函数包含了大量的信息:
args = Array.prototype.slice.call(arguments,2);
将函数中的参数转换成一个真正的数组,auguments虽然有length属性,但它并不是一个纯正的Array对象,同样不具有数组又有的方法。Array.prototype.slice.call可以将参数转化为一个数组,第二个参数的设定可以从第几个值开始生成参数数组。

例如

deferLoad(1.js,function(){alert("aa")},"bb","cc","dd");
args数组的值为["bb","cc","dd" ]。

<script/>标签生成并插入到<head/>中,文件引入成功后,开始执行交互,但问题是,怎么才能知道文件加载成功,script标签为我们提供了load事件,所以,我们可以将回调函数,放在script.onload中。

script.onload = function(){
      fu.apply(this,args);	
    };
没有兼容性问题,开玩笑了吧,有脚趾头想一下,IE下肯定有问题,IE 下script事件为onreadystatechange,这下上面函数中的if(script.readyState)便能明白。

通过这种方式引入的js文件如果有依赖,可以通过一下方式引入:

如果2.js对1.js文件有依赖,可以这样引入,

deferLoad("1.js",function(){
    deferLoad("2.js"),function(){
      alert("wjr");
    }
 })

    3.通过异步的方式引入文件

     通过ajax的方式来引入文件,也可以解决加载阻隔的问题,但如果多个文件之间有依赖关系,这种引入方式便会出现问题。

好吧,知道的解决方式就这些了,大家可以根据实际情况,灵活使用。

ok,本文结束!

转载于:https://my.oschina.net/u/564368/blog/143460

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值