转载于:http://www.cnblogs.com/mofish/archive/2011/09/29/2195256.html

所有浏览器在下载JS的时候,会阻止一切其他活动,比如其他资源的下载,内容的呈现等等。至到JS下载、解析、执行完毕后才开始继续并行下载其他资源并呈现内容。

有人会问:为什么JS不能像CSS、image一样并行下载了?这里需要简单介绍一下浏览器构造页面的原理,
当浏览器从服务器接收到了HTML文档,并把HTML在内存中转换成DOM树,在转换的过程中如果发现某个节点(node)上引用了CSS或者
IMAGE,就会再发1个request去请求CSS或image,然后继续执行下面的转换,而不需要等待request的返回,当request返回
后,只需要把返回的内容放入到DOM树中对应的位置就OK。但当引用了JS的时候,浏览器发送1个js
request就会一直等待该request的返回。因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,比如使用
document.write 或
appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以
就会阻塞其他的下载和呈现.

阻塞下载图:下图是访问blogjava首页的时间瀑布图,可以看出来开始的2个image都是并行下载的,而后面的2个JS都是阻塞下载的(1个1个下载)。

嵌入JS的阻塞下载

嵌入JS是指直接写在HTML文档中的JS代码。上面说了引用外部的JS会阻塞其后的资源下载和其后的内容呈现,哪嵌入的JS又会是怎样阻塞的了,看下面的列2个代码:
    代码1:

  < div >
      < ul >
          < li > blogjava </ li >
          < li > CSDN </ li >
          < li > 博客园 </ li >
          < li > ABC </ li >
          < li > AAA </ li >
      < ul >    
  </ div >
  < script  type ="text/javascript" >
     // 循环5秒钟
      var  n  =  Number( new  Date());
  var  n2  =  Number( new  Date());
 while ((n2  -  n)  <  ( 6 * 1000 )){
    n2  =  Number( new  Date());
  }
  </ script >
< div >
      < ul >
          < li > MSN </ li >
          < li > GOOGLE </ li >
          < li > YAHOO </ li >
      < ul >    
  </ div >

运行后,会发现代码1中,在前5秒中页面上是一篇空白,5秒中后页面全部显示。 代码2中,前5秒中blogjava,csdn等先显示出来,5秒后MSN才显示出来。
可以看出嵌入JS会阻塞所有内容的呈现,而外部JS只会阻塞其后内容的显示,2种方式都会阻塞其后资源的下载。

嵌入JS导致CSS阻塞加载的问题

CSS怎么会阻塞加载了?CSS本来是可以并行下载的,在什么情况下会出现阻塞加载了(在测试观察中,IE6下CSS都是阻塞加载,下面的测试在非IE6下进行):
   代码1(为了效果,这里选择了1个国外服务器的CSS):

< html  xmlns ="http://www.w3.org/1999/xhtml" >
     < head >
       < title > js test </ title >
       < meta  http-equiv ="Content-Type"  content ="text/html; charset=UTF-8"   /> 
       < link  type ="text/css"  rel ="stylesheet"  href ="http://69.64.92.205/Css/Home3.css"   />
     </ head >
     < body >
         < img  src ="http://www.blogjava.net/images/logo.gif"   />< br  />
          < img  src ="http://csdnimg.cn/www/images/csdnindex_piclogo.gif"   />
     </ body >
</ html >

时间瀑布图:

代码2(只加了1个空的嵌入JS):

< head >
     < title > js test </ title >
     < meta  http-equiv ="Content-Type"  content ="text/html; charset=UTF-8"   /> 
   < link  type ="text/css"  rel ="stylesheet"  href ="http://69.64.92.205/Css/Home3.css"   />
   < script  type ="text/javascript" >
         function  a(){}
   </ script >
</ head >
< body >
         < img  src ="http://www.blogjava.net/images/logo.gif"   />< br  />
         < img  src ="http://csdnimg.cn/www/images/csdnindex_piclogo.gif"   />
</ body >

时间瀑布图:

从时间瀑布图中可以看出,代码2中,CSS和图片并没有并行下载,而是等待CSS下载完毕后才去并行下载后面的2个图片,当CSS后面跟着嵌入的JS的时候,该CSS就会出现阻塞后面资源下载的情况。
    有人可能会问,这里为什么不说说嵌入的JS阻塞了后面的资源,而是说CSS阻塞了?
想想我们现在用的是1个空函数,解析这个空函数1ms就够,而后面2个图片是等CSS下载完1.3s后才开始下载。大家还可以试试把嵌入JS放到CSS前
面,就不会出现阻塞的情况了。
  
    根本原因:因为浏览器会维持html中css和js的顺序,样式表必须在嵌入的JS执行前先加载、解析完。而嵌入的JS会阻塞后面的资源加载,所以就会出现上面CSS阻塞下载的情况。

嵌入JS应该放在什么位置

1、放在底部,虽然放在底部照样会阻塞所有呈现,但不会阻塞资源下载。
   
   2、如果嵌入JS放在head中,请把嵌入JS放在CSS前面。
   
   3、使用defer
   
   4、不要在嵌入的JS中调用运行时间较长的函数,如果一定要用,可以用setTimeout来调用

PS:很多网站喜欢在head中嵌入JS,并且习惯放在CSS后面,比如看到的www.qq.com,当然也有很多网站是把JS放到CSS前面的,比如yahoo,google

外部JS的阻塞下载的更多相关文章

  1. 不阻塞浏览器的解析,待外部js下载完成后异步执行

    网站统计中的数据收集原理及实现(js埋点实现) - lastwhisper - CSDN博客 https://blog.csdn.net/l1212xiao/article/details/80450 ...

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

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

  3. html和js,外部js 的下载执行顺序

    当用户开始访问,首先下载html资源和外部js资源,在chrome中显示的是html先下载,然后下载外部js,外部js的下载顺序安引用顺序,但是下载到达情况则视情况而定,接着才是图片和其他资源,但是要 ...

  4. javascript笔记——js的阻塞特性[转载]

    JS具有阻塞特性,当浏览器在执行js代码时,不能同时做其它事情,即<script>每次出现都会让页面等待脚本的解析和执行(不论JS是内嵌的还是外链的),JS代码执行完成后,才继续渲染页面. ...

  5. 为什么要采用外部js文件

    这篇文章主要讲的是为什么要采用外部js文件,有什么好处. 为什么不把js内嵌在html中呢,这样不是好分析吗?对,这样你是好分析,同样的别人呢?不内嵌在html中有如下原因:   安全性: 只要查看页 ...

  6. javascript中外部js文件取得自身完整路径得办法

    原文:javascript中外部js文件取得自身完整路径得办法 有时候我们需要引入一个外部js文件,这个js文件又需要用到自己的路径或者是所在的目录,别问怎么又这么变态的需求,开发做久了各种奇葩需求也 ...

  7. js的阻塞特性

    JS具有阻塞特性,当浏览器在执行js代码时,不能同时做其它事情,即<script>每次出现都会让页面等待脚本的解析和执行(不论JS是内嵌的还是外链的),JS代码执行完成后,才继续渲染页面. ...

  8. AJAX载入外部JS文件到页面并让其执行的方法(附源码)

    一. 向HTML页面中动态添加JS文件(从外部载入)并让其执行的两种方法 1.只适用于IE浏览器的简单方法: 先在文档中放置一张JS"空床"并添加ID:<script id= ...

  9. 高性能 js -- 无阻塞加载脚本

    参考: <<高性能JavaScript>> Nicbolas C. Zakas 著 javascript代码的下载和执行过程会阻塞浏览器的其他进程, 比如页面的绘制, 遇到&l ...

随机推荐

  1. [Golang学习笔记] 01 工作区和GOPATH

    Go语言3个环境变量: GOROOT:GO语言按照根路径,也就是GO语言的安装路径. GOPATH:若干工作区目录的路径.是我自己定义的工作空间. GOBIN:GO程序生成的可执行文件(executa ...

  2. R语言学习笔记(二十四):plyr包的用法

    plyr 这个包,提供了一组规范的数据结构转换形式. Input/Output list data frame array list llply() ldply() laply() data fram ...

  3. 20155215 2016-2017-2 《Java程序设计》第6周学习总结

    20155215 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 stream:串流.抽象化输入/输出概念.将数据从来源取出,使用输入串流:将数据写入 ...

  4. 20155235 2016-2017-2 《Java程序设计》第十周学习总结

    20155235 2016-2017-2 <Java程序设计>第十周学习总结 教材学习内容总结 计算机网络 计算机网络由若干结点和连接这些结点的链路组成.网络中的结点可以是计算机.集线器. ...

  5. 20155330 2016-2017-2 《Java程序设计》第三周学习总结

    20155330 2016-2017-2 <Java程序设计>第三周学习总结 教材学习内容总结 学习目标 区分基本类型与类类型 理解对象的生成与引用的关系 掌握String类和数组 理解封 ...

  6. 20145226 《Java程序设计》第4周学习总结

    教材学习内容总结 学习目标 理解封装.继承.多态的关系 理解抽象类与接口的区别 掌握S.O.L.I.D原则 了解模式和设计模式 能正确覆盖方法 了解垃圾回收机制 掌握Object类 掌握enum 教材 ...

  7. GridSQL--Stado 学习初步

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL集群方案相关索引页     回到顶级页面:PostgreSQL索引页 作者  高健@博客园   luckyjackgao ...

  8. 解决 mybatis 的覆盖问题 以及避免手写大量mapper的方法

    只需要先实现覆盖不追加的方法: 然后再把所有需要改动mapper的方法抽离出来即可

  9. php-laravel安装与使用

    1.框架作用    提供了一些主体功能,方便开发者快速开发 2.PHP框架    laravel    ThinkPHP 3.首先要安装composer软件    1.作用        主要管理PH ...

  10. python全栈开发-面向对象-进阶

    python_day_18 1,面向对象的三大特性是什么?继承,多态,封装2,什么是面向对象的新式类?什么是经典类?凡是继承object类都是新式类.凡是不继承object类都是经典类.3,面向对象为 ...