高性能javascript筆記:關於腳本的優化


腳本的阻塞特性:把腳本放在底部

<script>標簽因腳本的加載,解析,運行而暫時整個頁面的下載和解析過程。如果把它放在<head>標簽里面。通常表現為:頁面打開時,首先顯示為一副空白的頁面。

因為腳本阻塞其他頁面資源的下載,所以推薦的方法就是:將所有的<script>標簽放在盡可能接近<body>標簽底部的位置即</body>之前。盡量減少對整個頁面下載的影響。

減少腳本的數量

當頁面解析每碰到一個<script>時,緊接着都會有一段時間用於js代碼的運行,最小化這些延遲時間可以改善頁面的性能。另外,對於外部js文件,會發出http請求,每個http請求都會產生額外的性能,下載一個100k的js文件要比下載4個25k的js文件要快,所以合並js有助於改善頁面的性能。

精簡js源代碼及壓縮腳本(gzip)

精簡js源代碼是指去除一個js文件中一切與運行無關的內容,包括注釋和不必要的空格,使js源文件體積更小,下載更快。推薦使用JSMinDojo Compressor;壓縮腳本需要在服務器做相應的配置,同樣適用於樣式表。

非阻塞加載腳本

非阻塞加載腳本是等頁面加載完后再加載Javascript源碼。從技術角度來說,這意味着在window的load事件發出后開始下載腳本。
延遲腳本:HTML4為<script>添加了一個defer屬性,這個屬性指明該腳本不會修改DOM,所以代碼可以稍后執行。僅IE和FF3.5支持,其他瀏覽器依然阻塞。代碼如下

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

任何支持帶有defer屬性的<script>元素在DOM加載完之前是不會被執行的,不管是內聯腳本還是外部文件,所以它可以放到頁面的任何位置。

動態添加腳本元素:<script>元素與其它元素一樣,可以通過Javascript從文檔中添加,移動,刪除。代碼如下

1 var script = document.createElement("script");
2 script.type = "text/javascript";
3 script.onload=function(){
4      //表示已經加載完
5 };
6 script.src = "file.js";
7 document.getElementsByTagName("head")[0].appendChild(script);

file.js文件當元素添加到頁面后立刻開始下載,重點在於無論在何處啟動下載,文件的下載和運行都不會阻塞其他頁面資源的處理。因為可能要經常使用到,所以可以封裝成一個跨瀏覽器的函數,方便以后使用:

 1 function asyncLoadScript(url,callback){
 2     var script = document.createElement("script");
 3     script.type = "text/javascript";
 4     if(script.readyState){//ie
 5         script.onreadystatechange = function(){
 6             if(script.readyState == "loaded" || script.readyState == "complete"){
 7                 script.onreadystatechange = null;
 8                 callback();
 9             }
10         }
11     }else{//other
12         script.onload = function(){
13             callback();
14         };
15     }
16     script.src = url;
17     document.body.appendChild(script);
18 }
19 //加載多個js,保證其順序
20 asyncLoadScript("file1.js",function(){
21     asyncLoadScript("file2.js",function(){
22         asyncLoadScript("file3.js",function(){
23             //所有js加載完成
24         });        
25     });    
26 });

還有一種方法就是利用XMLHttpRequest對象異步加載js文件,此方法的優點是:在js文件加載完后才創建script元素,所以它下載后不會自動執行。缺點是js文件必須與頁面放在同一個域內,不能從CDN(內容分發網絡)下載,一般來說大型網站不會使用這種方法。代碼如下:

 1 //跨瀏覽器創建XHR對象
 2 function createXHR(){
 3     if(typeof XMLHttpRequest != "undefined"){
 4         createXHR = function(){
 5             return new XMLHttpRequest();
 6         };
 7     }else if(typeof ActiveXObject != "undefined"){
 8         createXHR = function(){
 9             if(typeof arguments.callee.activeXString != "string"){
10                 var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"];
11                 for(var i=0; i<versions.length; i++){
12                     try{
13                         var xhr = new ActiveXObject(versions[i]);//試探瀏覽器支持能力
14                         arguments.callee.activeXString = versions[i];//把瀏覽器支持的XHR版本保存在activeXString屬性中
15                         return xhr;
16                     }
17                     catch(ex){
18                         //skip
19                     }
20                 }    
21             }
22             return new ActiveXObject(arguments.callee.activeXString);
23         };
24     }else{
25         createXHR = function(){
26             throw new Error("No XMLHttpRequest object available.");
27         };
28     }
29     return createXHR();
30 }
31 //利用XHR對象異步加載JS
32 function XHRLoadScript(url,callback){
33     var xhr = createXHR();
34     //為保持跨瀏覽器兼容性,必須在調用open()之前指定onreadystatechange事件處理程序
35     xhr.onreadystatechange = function(){
36         if(xhr.readyState == 4){
37             if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
38                 var script = document.createElement("script");
39                 script.type = "text/javascript";
40                 script.text = xhr.responseText;
41                 document.body.appendChild(script);
42                 
43                 callback();
44             }
45         }
46     };
47     xhr.open("get",url,true);
48     //盡管不發送數據,但對於某些瀏覽器來說這個參數是必需的
49     xhr.send(null);
50     
51 }

使用其它庫來加載js

1、Yahoo Search的lazyload      用法: LazyLoad.js([urlString|urlArray],function(){});
2、Kyle Simpson的LABjs         用法:$LAB.script(firstURL).script(secondURL).wait(function(){});


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM