posts - 36, comments - 419, trackbacks - 0, articles - 0
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

外部JS的阻塞下载

    所有浏览器在下载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:
<</span>div>
        ul>
            
li>blogjavaspan style="color: #800000;">li>
            
li>CSDNspan style="color: #800000;">li>
            
li>博客园span style="color: #800000;">li>
            
li>ABCspan style="color: #800000;">li>
            
li>AAAspan style="color: #800000;">li>
        
ul>    
    
span style="color: #800000;">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());
     }
    
span style="color: #800000;">script>
  
div>
        
ul>
            
li>MSNspan style="color: #800000;">li>
            
li>GOOGLEspan style="color: #800000;">li>
            
li>YAHOOspan style="color: #800000;">li>
        
ul>    
    
span style="color: #800000;">div>

    代码2(test.zip里面的代码与代码1的JS代码一模一样):
 
div>
        
ul>
            
li>blogjavaspan style="color: #800000;">li>
            
li>CSDNspan style="color: #800000;">li>
            
li>博客园span style="color: #800000;">li>
            
li>ABCspan style="color: #800000;">li>
            
li>AAAspan style="color: #800000;">li>
        
ul>    
    
span style="color: #800000;">div>
    
script type="text/javascript" src="http://www.blogjava.net/Files/BearRui/test.zip">span style="color: #800000;">script>
  
div>
        
ul>
            
li>MSNspan style="color: #800000;">li>
            
li>GOOGLEspan style="color: #800000;">li>
            
li>YAHOOspan style="color: #800000;">li>
        
ul>    
    
span style="color: #800000;">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 testspan style="color: #800000;">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" />
            
span style="color: #800000;">head>
            
body>
                
img src="http://www.blogjava.net/images/logo.gif" /><</span>br />
                
img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
            
span style="color: #800000;">body>
            
span style="color: #800000;">html>
  时间瀑布图:
   

   代码2(只加了1个空的嵌入JS):
 head>
    
title>js testspan style="color: #800000;">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(){}
  
span style="color: #800000;">script>
    
span style="color: #800000;">head>
    
body>
        
img src="http://www.blogjava.net/images/logo.gif" /><</span>br />
        
img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
    
span style="color: #800000;">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


[作者]:BearRui(AK-47)
[博客]: http://www.blogjava.net/bearrui/
[声明]:本博所有文章版权归作者所有(除特殊说明以外),转载请注明出处.
英雄,别走啊,帮哥评论下:  

精彩推荐 好文要顶 水平一般 看不懂 还需努力

评论

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-08 17:09 by rox
很受用,谢谢了!

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-08 18:04 by 隔叶黄莺
谢谢,很受用。

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-08 22:45 by BearRui(AK-47)
谢谢楼上2位的支持.

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-09 09:14 by xming
这个博主 是用什么浏览器来测试的??、



不同浏览器有区别吗???

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-09 09:23 by BearRui(AK-47)
@xming

firefox,ie6,chrome都测试过,就最后1个CSS阻塞的问题在IE6下不一样,IE6下好像CSS一直都是阻塞下载的,不过放在上面位置都一样,这个还不是很清楚什么原因。

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-10 18:36 by anniezheng
谢谢了,现在正在用FineReport报表软件,应该回有点帮助。

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-11 03:53 by 凌晨风
Study...... Thank you!

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-11 20:20 by myProMark
收藏了

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-13 12:20 by 沧桑雨迢迢
非常精辟的分析

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-04-13 14:33 by BearRui(AK-47)
@沧桑雨迢迢
谢谢,^_^

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-05-11 00:15 by 税国政
很受益啊

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-05-11 08:41 by BearRui(AK-47)
@税国政
^_^

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?[未登录]  回复  更多评论   

2010-05-12 17:55 by 阿健
恍然大悟的感觉!多谢楼主!

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-05-12 20:27 by BearRui(AK-47)
@阿健
言重了,^_^

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-05-22 12:19 by KinKo
很精彩,非常感谢!!!

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-06-17 15:17 by niko7
受教了,谢谢

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-06-23 14:18 by raymond
受教。以后可以借鉴。

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-07 19:20 by 圣光永恒
文章很不错,软件用过,也很好用,支持了:-D

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-08 08:55 by BearRui(AK-47)
@圣光永恒

谢谢支持

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-08 16:57 by 朱少
很好很不错来支持一下

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-13 19:36 by nauxiaoyao
有效的阻止了跳转

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-13 20:29 by BearRui(AK-47)
@nauxiaoyao
阻止跳转,什么意思???

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-13 20:30 by BearRui(AK-47)
@朱少

谢谢,^_^

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-16 10:08 by 蔡创
谢谢楼主分享··
正在为优化web发愁。。。 谢谢···

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-16 10:12 by BearRui(AK-47)
@蔡创
不客气,^_^

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-16 15:20 by ssy
while((n2 - n) (6*1000))
改为while((n2 - n)<(6*1000))

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-22 10:27 by 徐培华
麻烦啊。评论还要弄个验证码

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-07-22 15:35 by BearRui(AK-47)
@徐培华
呵呵,没有注册是这样,防止垃圾广告回复嘛

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-08-10 19:51 by 带着爱远行
楼主讲得挺精辟的,以前一直没注意,想放哪就放哪,现在受益了,原来HTML在加载JS时为了防止DOM树的改变会选择阻塞其他DOM元素的下载的!我觉得哇,需要链接的.js文件还是放在head里面比较好,页面内部的放在末尾比较好,

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-08-10 20:03 by 带着爱远行
补充一下:关于CSS为什么要放在head里面,放在head里面的目的是为了最先加载,试想一下:如果你吧CSS的声明放在了下面,那么当你加载的页面元素套用了一个CSS的时候,HTML就会发送请求去加载这个CSS.如果你一次性就在最开始的时候把CSS都加载完,就不会有多余的CSS请求,而且可能浏览器在加载了一个CSS之后并遇到后面的CSS还会重复加载,欢迎批评指正

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-10-11 13:22 by 曾江莉
很不错的文章,学习了~~

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-10-19 11:18 by BearRui(AK-47)
@曾江莉
^_^,欢迎常来

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-10-29 17:30 by galex
不得不顶。很的写好

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-10-29 17:39 by BearRui(AK-47)
@galex
谢谢,^_^

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-11-26 15:18 by 张浩正
很 好 说的很好

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2010-12-13 13:48 by 福尔螺丝
很受用,还特意去买了一本 网站前端性能优化的书籍

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2011-01-07 15:28 by F1HELP
给力!

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2011-05-27 17:12 by wrong.t
不错的文章,受益匪浅。

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2011-06-20 11:53 by chao
写得不错吗

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2013-09-22 17:38 by keithen.leo
使用火狐23.1测试,发现页面中的外联脚本是与外联js同时加载的,无论放置位置在head或页面底部,然后再加载dom中的图片

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2013-12-08 10:39 by Troland
雅虎不是建议JS放在body底部吗?为什么还会在头部?是一些必要的JS要放在头部吗?

# re: 高性能web开发 - 如何加载JS,JS应该放在什么位置?  回复  更多评论   

2015-09-24 10:42 by wb
底部是指html标签内还是html标签外?

只有注册用户登录后才能发表评论。


网站导航: