javascript性能優化:建立javascript無阻塞腳本

  javaScript 在瀏覽器中的運行性能,在web2.0時代顯得尤其重要,成千上萬行javaScript代碼無疑會成爲性能殺手,javascript

在較低版本的瀏覽器執行JavaScript代碼的時候,因爲瀏覽器只使用單一進程來處理ui界面刷新和JavaScript腳本執行,css

這意味着在加載javascript文件的時候不能同時作任何其餘的事情。   在加載的同時形成了用戶交互阻塞;html


 

  理論上來講,把樣式與行爲有關的腳本放在一塊兒率先加載,這樣有利於確保正確的用戶體驗,例以下面的代碼:html5

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<title>javascript</title>
	<script src="file.js" type="text/javascript" charset="utf-8"></script>
	<script src="file1.js" type="text/javascript" charset="utf-8"></script>
	<link rel="stylesheet" type="text/css" href="file.css"/>
	<link rel="stylesheet" type="text/css" href="file1.css"/>
	<link rel="stylesheet" type="text/css" href="file2.css"/>
</head>
<body>

</body>
</html>

 

  這種看似合理的代碼其實有着很嚴重的性能問題:在javascript文件加載並執行完成以前會阻止頁面進行渲染,咱們的web頁面會出現一片空白java

沒法與之正常交互,這稱之爲腳本阻塞web

  

  因爲腳本會阻塞頁面其餘資源的加載 咱們能夠把全部的script標籤放在</body>以前  在頁面加載的最後來加載javascript文件ajax

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>javascript</title>
    
    <link rel="stylesheet" type="text/css" href="file.css"/>
    <link rel="stylesheet" type="text/css" href="file1.css"/>
    <link rel="stylesheet" type="text/css" href="file2.css"/>
</head>
<body>
    
    <!--推薦全部的js文件位置-->
    <script src="file.js" type="text/javascript" charset="utf-8"></script>
    <script src="file1.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>


-----------優化javascript的首要任務,將js文件放置在頁面底部;chrome

 

   那如何建立一個無阻塞的腳本呢?瀏覽器

無阻塞腳本的祕訣在於,在頁面加載完成以後纔開始加載javascript代碼。 咱們要在window對象的load時間觸發後再下載並執行腳本,app

已知有不少種方式能夠實現這一效果,這裏簡單例舉一二:

 

  1.HTML5新特性 

    html5爲script標籤提供了兩個新的屬性 一個是defer 另外一個是async 它們採用的都是並行下載的方式; 在下載過程當中並不會形成頁面阻塞

它們的區別在於 defer表示等待頁面加載完成纔會執行,async則是它自己加載完成後就自動執行;

defer目前已被各大主流瀏覽器所兼容;

 

  2.建立動態腳本元素;這很容易使頁面渲染完成以後再進行腳本加載;

例如:

  

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>javascript</title>
    
</head>
<body>
    
    <script type="text/javascript">
        var script = document.createElement("script");
        script.src = "ztf.js";
        document.getElementsByTagName("head")[0].appendChild(script);
    </script>
</body>
</html>

  咱們使用標準的dom方法document.createElement來動態的建立一個script元素並指定它的src;這行成了一個動態的腳本模式;在任意時刻插入任意的javascript代碼都會被瀏覽器執行;(建立的script最好不要插入到body裏面;這樣可能會引發ie拋出一個‘操做已終止’的錯誤信息;)

  ff,opera,chrome和safari3以上版本的script標籤會在加載完成觸發onload事件。

  而在老版本ie下(ie6-10) 它會觸發一個readystatechange事件。<script>元素會提供一個readyState屬性,它的值在scr加載不一樣過程產生不一樣的變化;咱們一般會使用到 "loaded" 和 "complete"。

  經過「客戶端能力檢測」 (http://www.jxbh.cn/newshow.asp?id=1434&tag=2) 咱們能夠建立一個通用的動態加載javascript的函數:    

function loadScript(url,callback){
            var script = document.createElement("script");
            script.type="text/javascript";
            if(script.readyState){        //客戶端能力檢測  若是支持readyState則返回的是字符串 反之返回undefined
                script.onreadystatechange = function(){    //onreadystatechange事件
                    if(script.readyState=="loaden"||script.readyState=="complete"){
                        
                        script.onreadystatechange=null;
                        
                        callback();
                    }
                }
            }else{
                script.onload = function(){
                    callback();
                }
            }
            script.src = url;
            document.getElementsByTagName("head")[0].appendChild(script);
        }

這個函數接受兩個參數;javascript文件的url和完成加載後的回調函數。loadScript()函數的用法以下

loadScript("ztf.js",function(){
       alert("loadend")
});

若是須要的話,你能夠儘量多的加載javascript文件到頁面上,但必定要考慮清楚文件的加載順序,能夠不斷的使用callback回調函數加載多個javascript腳本;

 

另外還有一種,ajax動態請求加載腳本 在這裏筆者就不一 一說明 ,你們查閱有關文檔;

 

部份內容摘自《高性能javascript》

相關文章
相關標籤/搜索