javaScript——優化

javaScript是一門解釋性的語言、它不像java、C#等程序設計語言、由編譯器先進行編譯再運行、而是直接下載到用戶的客戶端進行執行。因此代碼本身的優劣就直接決定了代碼下載的速度以及執行的效率。

        1、減緩代碼下載時間:

        Web瀏覽器下載的是javaScript的源碼、其中包含的長變量名、註釋、空格和換行等多餘字符大大減緩了代碼下載的時間。這些字符對於團隊編寫時十分有效、但在最後工程完成上傳到服務器時、應當將它們全部刪除。例如:


view plaincopy to clipboardprint?
01.function showMeTheMoney(){ 
02.        if(!money){ 
03.                return false; 
04.        }else{ 
05.                ... 
06.        } 
07.} 

可優化成:


view plaincopy to clipboardprint?
01.function showMeTheMoney(){if(!money){return false;}else{...}} 


        這樣、優化後就節約了25個字節、倘若是一個大的javaScript工程、將節省出非常大的空間、不但提高了用戶的下載速度、也減輕了服務器的壓力。相信這樣的代碼大家見過不少、很多優秀的js插件源碼都這麼幹!

        另外、對於布爾型的值true和false、true都可以用1來代替,而false可以用0來代替。對於true節省了3個字節、而false則節省了4個字節、例如:


view plaincopy to clipboardprint?
01.var bSearch = false; 
02.        for(var i=0;i<aChoices.length&&!bSearch;i++){ 
03.            if(aChoices[i] == vValue) 
04.                bSearch = true ; 
05.        } 

替換成:


view plaincopy to clipboardprint?
01.var bSearch = 0; 
02.        for(var i=0;i<aChoices.length&&!bSearch;i++){ 
03.            if(aChoices[i] == vValue) 
04.                bSearch = 1 ; 
05.        } 

        替換了布爾值之後、代碼的執行效率、結果都相同、但節省了7個字節。

        代碼中常常會出現檢測某個值是否爲有效值的語句、而很多條件非的判斷就判斷某個變量是否爲"undefined"、"null"、或者"false"、例如:


view plaincopy to clipboardprint?
01.if(myValue != undefined){ 
02.            //...  
03.        } 
04.         
05.        if(myValue !=null){ 
06.            //...  
07.        } 
08.         
09.        if(myValue != false){ 
10.            //...  
11.        } 

        這些雖然都正確、但採用邏輯非操作符"!"也可以有同樣的效果、代碼如下:


view plaincopy to clipboardprint?
01.if(!myValue){ 
02.            //...  
03.        } 

        這樣的替換也可以節省一部分字節、而且不太影響代碼的可讀性。類型的代碼優化還有將數組定義時的 new Array()直接用"[]"代替、對象定義時的 new Object()用"{}"代替等、例如:


view plaincopy to clipboardprint?
01.var myArray = new Array(); 
02.        var myArray = []; 
03.        var myObject = new Object(); 
04.        var myObject = {}; 

        顯然、第二行和第四行的代碼較爲精簡、而且也很容易理解。

        另外、在編寫代碼時往往爲了提高可讀性、函數名稱、變量名稱使用了很長的英文單詞、同時也大大增加了代碼的長度、例如:


view plaincopy to clipboardprint?
01.function AddThreeVarsTogether(firstVar,secondVar,thirdVar){ 
02.            return (firstVar+secondVar+thirdVar); 
03.        } 

可優化成:


view plaincopy to clipboardprint?
01.function A(a,b,c){return (a+b+c);} 

        注意:在進行變量名稱替換時、必須十分小心、尤其不推薦使用文本編輯器的"查找"、"替換"功能、因爲編輯器不能很好地區分變量名稱或者其他代碼。例如、希望將變量"tion"全部替換成"io"、很可能導致關鍵字"function"也被破壞。

        對於上面說的這些減少代碼體積的方法、有一些很實用的小工具可以自動完成類似的工作、例如ECMAScript Cruncher、JSMin、Online JavaScript Compressor等。

        2、合理聲明變量

        減少代碼的體積僅僅只能使得用戶下載的速度變快、但執行程序的速度並沒有改變。要提高代碼執行的效果、還得在各方面做調整。

        在瀏覽器中、JavaScript默認的變量範圍是window對象、也就是全局變量。全局變量只有在瀏覽器關閉才釋放。而JavaScript也有局部變量、通常在function中執行完畢就會立即被釋放。因此在函數體中要儘可能使用var關鍵字來聲明變量:


view plaincopy to clipboardprint?
01.function First(){ 
02.            a = "" ;   //直接使用變量  
03.        } 
04.        function Second(){ 
05.            alert(a); 
06.        } 
07.        First(); 
08.        Second(); 

        這樣、變量"a"就成爲了全局變量、直到頁面關閉時纔會被銷燬、浪費了不必要的資源、如果在"a"的前面加上"var"、這樣"a"就成爲了當前function的局部變量。在執行完First()便立即被銷燬。因此、在函數體中、如果不是特別需要的全局變量、都應當使用"var"進行聲明、從而節省系統資源。

       


        3、使用內置函數縮短編譯時間

        只要可能、應當儘量使用JavaScript的內置函數。因爲這些內置的屬性、方法都是用類似C、C++之類的言語編譯過的、運行起來比實時編譯的JavaScript快很多。例如計算指數函數、可以自己編寫:


view plaincopy to clipboardprint?
01.<html> 
02.  <head> 
03.    <base href="<%=basePath%>"> 
04.    <title>內置函數</title> 
05.    <meta http-equiv="pragma" content="no-cache"> 
06.    <meta http-equiv="cache-control" content="no-cache"> 
07.    <meta http-equiv="expires" content="0">     
08.    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 
09.    <meta http-equiv="description" content="This is my page"> 
10.    <script type="text/javascript"> 
11.        function myPower(iNum,n){ 
12.            var iResult = iNum ; 
13.            for(var i=0;i<n;i++) 
14.                iResult *= iNum ; 
15.            return iResult; 
16.        } 
17.        var myDate1 = new Date(); 
18.        for(var i=0;i<150000;i++){ 
19.            myPower(7,8);  //自定義方法 
20.        } 
21.        var myDate2 = new Date(); 
22.        document.write(myDate2 - myDate1); 
23.        document.write("<br/>"); 
24.        myDate1 = new Date(); 
25.        for(var i=0;i<150000;i++){ 
26.            Math.pow(7,8);  //採用系統內置方法 
27.        } 
28.        myDate2 = new Date(); 
29.        document.write(myDate2 - myDate1); 
30.    </script> 
31.  </head> 
32.  <body> 
33.  </body> 
34.</html> 

        我運行的結果是、自定義方法用了15、內置方法用了1(不同的計算機運行速度會有差別)、這樣就能看出、系統內置的方法要快很多。

       


        4、合理書寫if語句。

        if語句恐怕是所有代碼中使用最頻繁的、然而很可惜的是它的執行效率並不是很高。在用if語句和多個else語句時、一定要把最有可能的情況放在第一個、然後是可能性第二的、依此類推。例如預計某個數值在0~100之間出現的概率最大、則可以這樣安排代碼:


view plaincopy to clipboardprint?
01.if(iNum>0&&iNum <100){ 
02.            alert("在0和100之間"); 
03.        }else if(iNum>99&&iNum<200){ 
04.            alert("在100和200之間"); 
05.        }else if(iNum>199&&iNum<300){ 
06.            alert("在200和300之間"); 
07.        }else{ 
08.            alert("小於等於0或者大於等於300"); 
09.        } 

        總是將出現概率最多的情況放在前面、這樣就減少了進行多次測試後才能遇到正確條件的情況。當然也要儘可能減少使用else if 語句、例如上面的代碼還可以進一步優化成如下代碼:


view plaincopy to clipboardprint?
01.if(iNum>0){ 
02.            if(iNum<100){ 
03.                alert("在0和100之間"); 
04.            }else{ 
05.                if(iNum<200){ 
06.                    alert("在100和200之間"); 
07.                }else{ 
08.                    if(iNum<300){ 
09.                        alert("在200和300之間"); 
10.                    }else{ 
11.                        alert("大於等於300"); 
12.                    } 
13.                } 
14.            } 
15.        }else{ 
16.            alert("小於等於0"); 
17.        } 

        上面的代碼看起來比較複雜、但因爲考慮了很多代碼潛在的判斷問題、執行問題、因此執行速度要較前面的代碼快。

        另外、通常當超過兩種情況時、最好能夠使用switch語句。經常用switch語句代替if語句、可令執行速度快甚至10倍。另外、由於case語句可以使用任何類型、也大大方便switch語句的編寫。

 


        5、最小化語句數量

        腳本找哦個的語句越少執行的時間就越短、而且代碼的體積也會相應減少。例如使用var定義變量時可以一次定義多個、代碼如下:


view plaincopy to clipboardprint?
01.var iNum = 365; 
02.        var sColor = "yellow"; 
03.        var aMyNum = [8,7,12,3] ; 
04.        var oMyDate = new Date(); 

        上面的多個定義可以用var關鍵字一次性定義、代碼如下:


view plaincopy to clipboardprint?
01.var iNum = 365, sColor = "yellow" , aMyNum = [8,7,12,3],oMyDate = new Date() ; 

        同樣在很多迭代運算的時候、也應該儘可能減少代碼量、如下兩行代碼:


view plaincopy to clipboardprint?
01.var sCar = aCars[i]; 
02.        i++; 

        可優化成:


view plaincopy to clipboardprint?
01.var sCar = aCars[i++]; 

       


        6、節約使用DOM

        JavaScript對DOM的處理可能是最耗費時間的操作之一。每次JavaScript對DOM的操作都會改變頁面的表現、並重新渲染整個頁面、從而有明顯的時間消耗。比較快捷的方法就是儘可能不在頁面進行DOM操作、如下例中爲ul添加了10個條目。


view plaincopy to clipboardprint?
01.var oUl = document.getElementById("ulItem"); 
02.        for(var i=0;i<10;i++){ 
03.            var oLi = document.createElement("li"); 
04.            oUl.appendChild(oLi); 
05.            oLi.appendChild(document.createTextNode("Item "+i)); 
06.        } 

         以上代碼在循環中調用oUl.appendChild(oLi)、每次執行這條語句後、瀏覽器就會重新渲染頁面、其次給列表添加文本節點oLi.appendChild(document.createTextNode("Item "+i))、這也會造成頁面被重新渲染。因此每次運行都會造成兩次重新渲染頁面、共20次。

        通常應當儘可能減少DOM的操作、將列表項目在添加文本節點之後在添加、併合理地使用createDocumentFragment()、代碼如下:


view plaincopy to clipboardprint?
01.var oUl = document.getElementById("ulItem"); 
02.        var oTemp = document.createDocumentFragment(); 
03.        for(var i=0;i<10;i++){ 
04.            var oLi = document.createElement("li"); 
05.            oLi.appendChild(document.createTextNode("Item "+i)); 
06.            oTemp.appendChild(oLi); 
07.        } 
08.        oUl.appendChild(oTemp); 


 

 

發佈了45 篇原創文章 · 獲贊 10 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章