脚本无阻塞加载

(图片来源:http://www.cnblogs.com/sharpxiajun/p/4072396.html)

这是清除浏览器缓存后,第一次访问百度首页的场景,在Firefox的瀑布图中可以看到:javascript文件下载完毕后,有一段时间没有请求处理。这段时间过后,请求才会接着执行,这段时间就是HTTP请求阻塞。

当浏览器遇到<script>标签时,浏览器会停止处理页面,先执行Javascript代码,然后再继续解析和渲染页面。在这个过程中,页面和用户的交互完全被阻塞了。通常表现为显示空白页面,用户无法浏览内容。

现在的浏览器都支持并行下载文件,比如上图同时下载多个图片。而且,IE8 、FireFox3.5、Safari4和Chrome2都支持并行下载javascript文件,但是javascript文件的下载会阻塞其他资源的下载。尽管脚本的下载过程不会相互影响,但是页面仍然需要等待javascript的执行完毕才能继续。所以,新浏览器通过并行下载提高了性能,但是脚本阻塞问题仍然没有解决。

解决方法有:

(1)把<script>标签放到</body>闭合之前

由于脚本会阻塞其他资源的下载,因此推荐把所有的<script>标签尽可能的放到<body>标签的底部。

(2)脚本合并,减少<script>标签的数量

每次遇到<script>标签,浏览器都要发一次HTTP请求。而HTTP请求耗时是web性能的最大的影响之一。

(3)动态脚本加载

忙指示(忙指示现象有:浏览器选项卡的旋转圆圈,鼠标变成漏斗状,浏览器左下状态栏显示正在加载某某url)标记结束了,就表明页面的加载操作结束了,为了防止js脚本阻塞页面的加载。我们就要让那些不用于页面初始化展示的js代码的加载和执行在浏览器忙指示结束后触发。结束的标志就是onload事件触发,因此我们可以把那些有页面加载无关的js脚本放到onload事件里。

<span style="font-size:14px;">  var script=document.createElemetn("script");

  script.type="text/javascript";

  script.src="file.js";;

  document.getElementsByTagName("head").appendChild(script);</span>

使用动态脚本这种技术重点在于:文件的下载和执行过程不会阻塞页面其他进程。通常要把新创建的<script>标签添加到<head>标签里比添加到<body>标签里更保险。但是这种情况下,必须跟踪并确保脚本下载完成并准备就绪。

  标准浏览器:

符合w3c标准的浏览器,script元素接收完成式,触发一个load事件。

var script =document.createElement("div");
script.type="text/javascript";

script.onload=function(){
  alert("ok");
};

script.src="file.js";

document.getElementsByTagName("head")[0].appendChild(script);

IE支持另外一种实现方式,触发readystatechange事件。<script>元素提供一个readyState属性,它的值在外链下载过程中不同阶段发生变化,属性有五个值:

“uninitializd”   初始状态

“loading”       开始下载

“loaded”       下载完成

“interactive”  数据下载完成但尚不可用

“complete”  所有数据已准备就绪

最有用的的两个状态是:"loaded"和"complete"。

var script=document.createElement("script");

script.type="text/javascript";
//IE
script.onreadystatechange=function(){
   if(script.readyState=="loaded"||script.readyState="complete"){
   script.onreadystatechange=null;
   alert("ok");
 }
}

兼容标准及IE浏览器:

function loadScript(url ,callback){
    var script=document.createElement("script");
    script.src="text/javascript";

     if(script.readyState){//IE
         script.onreadyStateChange=function(){
         if(script.readyState=="loaded"||script.readyState=="complete"){
                    script.onreadystatechange=null;

                           callback();
                }

           };
    }else{//其他浏览器

     script.onload=function(){
        callback();
     };
  }
      script.src=url;
      document.getElementsByTagName("head")[0].appendChild(script);

 }

单个文件:

loadScript("file1.js",function(){

  alert("ok")
});

添加多个文件:

loadScript("file1.js",function(){
      loadScript("file2.js",function(){
         loadScript("file3.js",function(){
          alert("ok");
          });
      });
 });

添加多个文件会对管理带来困难,可以借助jquery的$.Deferred()和$.when()避免回调地狱。(http://blog.csdn.net/vuturn/article/details/45024767)

推荐的无阻塞模式

<script type="text/javascript" src="test.js"></script>

<script type="text/javascript">
loadScript("file.js",function(){
   alert("ok");
});

</script>

参考:(http://www.cnblogs.com/sharpxiajun/p/4072396.html)

《高性能JavaScript 》

时间: 2024-10-15 02:43:58

脚本无阻塞加载的相关文章

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

原文:探真无阻塞加载javascript脚本技术,我们会发现很多意想不到的秘密 下面的图片是我使用firefox和chrome浏览百度首页时候记录的http请求 下面是firefox: 下面是chrome: 在浏览百度首页前我都将浏览器的缓存全部清理掉,让这个场景最接近第一次访问百度首页的情景. 在firefox的请求瀑布图里有个表现非常之明显:就是javascript文件下载完毕后,有一段时间是没有网络请求被处理的,这段时间过后http请求才会接着执行,这段空闲时间就是所谓的http请求被阻塞

无阻塞加载脚本

一个页面,从被请求访问,到用户可以看到页面.操作页面,到最后页面完全加载完毕,中间需要经历一个相当奇幻的过程,这个过程的速度被"web性能师"孜孜不倦.前赴后继的优化.本文讨论的是其中一个优化. 浏览器线程和阻塞 虽然大家耳熟能详的一句话是: JavaScript是单线程的. 但是: 浏览器当然不是单线程的. 浏览器的多线程中,有的线程负责加载资源,有的线程负责执行脚本,有的线程负责渲染界面,有的线程负责轮询.监听用户事件. 这些线程,根据浏览器自身特点以及web标准等等,有的会被浏览

性能优化之无阻塞加载脚步方法比较

秋招结束了~~,好像偷懒了很久,没更博了.总结一下自己近来看书的内容. 说明一下,内容大部分来自<高性能网站建设进阶指南>. 乱入内容 Web应用和传统桌面应用有一个共同的目标:尽可能快地响应用户输入. 怎样才算是快?Jakob Nielsen是Web可用性领域知名且备受推崇的专家,引用他的观点来说就是:如果JavaScript代码执行时间超过了0.1秒,页面将会给人不够平滑快捷的感觉,如果执行时间超过了1秒,则会感到应用程序缓慢,超过了10秒,那么用户将会非常沮丧. 性能分析器:Firebu

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

浏览器加载静态资源和js的方式都是线性加载,所以一般情况可以将js放到</body>前,防止UI线程的阻塞. 而某些时候我们既希望js在整个网页的头部就加载,又担心js阻塞导致网站加载缓慢,就可以用到无阻塞加载js技术. Dynamic Script Elements 动态脚本元素 DOM允许我们使用Javascript动态创建HTML的几乎所有文档内容,一个新的<script>元素可以非常容易的通过标准DOM创建: var script = document.createElem

无阻塞加载脚本的方案

1.动态加载脚本 <script type="text/javascript"> function loadScript(url){ var script=document.createElement("script"); script.type="text/javascript"; script.src=url; document.body.appendChild(script); } loadScript("js/sid

无阻塞加载脚本,按序执行

通常加载页面的时候,对于组件是并行下载的,现代大部分浏览器对于Js同样也是支持并行下载,但是在脚本下载.解析并执行完毕之前,不会开始下载任何其他内容. 正常引入: 可以看出,在脚本下载完毕后的一段时间内(该时间在解析执行脚本),不会对其他组件进行下载,以下几种方案解决该问题. 1. XHR Eval加载脚本: 即使用ajax引入脚本,并通过eval对其执行. 代码: var xhrObj = getXHRObject(); xhrObj.onreadystatechange = function

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

原文转自:http://blog.jobbole.com/78191/ Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中,其中一条是将JS放在底部 .原因是,事实上,大多数浏览器使用单进程处理UI和更新Javascript运行等多个任务,而同一时间只能有一个任务被执行.Javascript运行了多长时间,那么在浏览器空闲下来响应用户交互之前的等待时间就有多长. 从基本层面说,这意味着<script>标签的出现使整个页

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

Javascript在浏览器中的性能,可以说是前端开发者所要面对的最重要的可用性问题. 在Yahoo的Yslow23条规则当中,其中一条是将JS放在底部 .原因是,事实上,大多数浏览器使用单进程处理UI和更新Javascript运行等多个任务,而同一时间只能有一个任务被执行.Javascript运行了多长时间,那么在浏览器空闲下来响应用户交互之前的等待时间就有多长. 从基本层面说,这意味着<script>标签的出现使整个页面因脚本解析.运行而出现等待.不论实际的 JavaScript 代码是内

web性能优化之---JavaScript中的无阻塞加载性能优化方案

一.js阻塞特性 JS 有个很无语的阻塞特性,就是当浏览器在执行JS 代码时,不能同时做其他任何事情,无论其代码是内嵌的还是外部的. 即<script>每次出现都会让页面等待脚本的解析和执行(不论JS是内嵌的还是外链的),JS代码执行完成后,才继续渲染页面. 二.优化方案 1.尽管脚本的下载过程并不会相互影响,但页面仍然必须等待所有JS下载并执行完成才能继续.所以尽可能将所有<script>标签放置在页面底部,紧靠关闭标签</body>的上方.此方法可以保证页面在脚本运