JS脚本文件的位置对页面加载性能影响以及无阻塞脚本(javascript)模式

   JS的阻塞特性:当<script>出现的时候,页面必须等待脚本文件的加载、解析、执行完毕后才能继续进行页面的渲染。不管脚本文件是以内联形式还是外部引入的形式出现在<script>中,页面的加载和渲染都必须停下来等待脚本文件的执行完成。因为在脚本文件中可能会修改页面的内容。这就会出现一个问题,当HTML文件中引入很多的外部脚本文件和内联脚本时,可能会导致页面的严重阻塞,影响页面的加载和渲染,用户体验特别的差。因而需要寻找适当的方法来减小脚本文件对页面加载带来的影响。

改善性能的几种方式:

 1、 我们都知道脚本文件既可以存放在<head>标签中也可以存放在<body>标签中,并且是循序重复出现的如果将将本文件放在<head>中,如下:

    <!DOCTYPE html>  
    <html >  
    <head>  
      <meta charset="utf-8">  
      <title></title>  
      <script src="script.js"></script>  
          <script src="file1.js"></script>  
 <script src="file2.js"></script>  
 <script src="file3.js"></script>  
<link rel="styleSheet" type="text/css" hhref="styles.css"></link>
    </head>  
    <body onload="init()"> 
    <p> swapCache方法示例</p>
    </body>  
    </html>  

     在上述代码在<head>中加载了四个JS文件,由于脚本阻塞页面的渲染,所以只有当脚本全部下载完并执行完毕后,页面才会开始渲染,在body标签之前是不会渲染任何部分的。同时在加载JS文件时,只有当前一个加载完毕并执行完毕后才会进行下一个JS文件的加载和执行,在早期的浏览器中都是不能进行JS文件的并行下载的,不过目前很多主流的浏览器都支持异步加载JS包,但是页面渲染的其他资源如图片等,仍然或因为JS的加载而阻塞,所以通常建议将JS文件尽量放在<body>标签中,以尽量减少对整个页面下载的影响。

2、由于每个<script>标签的初始下载时都会阻塞页面的渲染,所以尽量减少<script>标签的数量有助于改善页面阻塞情况。也就是说内联JS文件尽量合并,外部引入的文件如果可以合并最好不过,通常单个下载100KB文件比下载4个25KB文件更快。

3、无阻塞脚本的秘诀在于,在页面加载完毕后才加载javascript代码,也就是说当触发window对象的onload事件后再下载脚本。有如下几种方式实现这一效果:

(1)利用属性:async/defer

   async:异步加载脚本同时在脚本加载的时执行脚本,不影响页面的加载和渲染

   defer:异步加载脚本同时进行页面渲染,但脚本的执行需要等到页面加载完毕

  <!DOCTYPE html>  
   <html >  
   <head>  
    <meta charset="utf-8">  
    <title></title>  
    <script defer>
       alert("defer");
    </script>  
    <script >
       alert("script");
   </script>  
   <script>
      window.onload=function(){
      alert("onload")
       }
  </script>
    <link rel="styleSheet" type="text/css" hhref="styles.css"></link>
    </head>  
    <body onload="init()"> 
    <p> swapCache方法示例</p>
    </body>  
    </html>  

上述代码在不支持defer的浏览器弹出的顺序依次为:defer,script,load;在支持defer的浏览器中的弹出顺序为:script,defer,load。带有defer属性的标签是在onload的事件执行之前执行的,也即当页面加载完后执行带有defer属性的<script>中大JS代码。但是加载与页面加载异步执行的。

(2)利用动态脚本元素即通过document.createElement("script")动态生成脚本

   var script=document.craateElement("script");
   script.type="text/script"
  script.src="file.js";
   docuemnt.getElementsByTagName("head")[0].appendChild("script");

这种方法的优势在于无论什么时候启动加载,问价的下载和执行都不会阻塞页面的其他进程。该方法具有挂浏览器的兼容性和易用性优势,是最为通用的无阻塞加载的解决方法。

(3)XMLHttpRequest脚本注入的方法

利用XHR对象,借助它进行javascript脚本的下载,最后通过动态创建<script>元素将代码注入到页面当中

var xhr=new XMLHttpRequest();
xhr.open("get","file.js",true);
xhr.onreadystatechange=function(){
    if(xhr.state==4&&xhr.status==200)
     var script=docuemnt.createElement("script");
    script.type="text/script";
   script.text=xhr.reaponseText;
  document.body.appendChild(script);
}

 

posted @ 2016-08-01 13:00  heshan珊  Views(991)  Comments(0Edit  收藏  举报