詳細(xì)javaScript代碼的優(yōu)化
javaScript是一門(mén)解釋性的語(yǔ)言、它不像java、C#等程序設(shè)計(jì)語(yǔ)言、由編譯器先進(jìn)行編譯再運(yùn)行、而是直接下載到用戶(hù)的客戶(hù)端進(jìn)行執(zhí)行。因此代碼本身的優(yōu)劣就直接決定了代碼下載的速度以及執(zhí)行的效率。
1、減緩代碼下載時(shí)間:
Web瀏覽器下載的是javaScript的源碼、其中包含的長(zhǎng)變量名、注釋、空格和換行等多余字符大大減緩了代碼下載的時(shí)間。這些字符對(duì)于團(tuán)隊(duì)編寫(xiě)時(shí)十分有效、但在最后工程完成上傳到服務(wù)器時(shí)、應(yīng)當(dāng)將它們?nèi)縿h除。例如:
- function showMeTheMoney(){ if(!money){ return false; }else{ ... } }
可優(yōu)化成:
- function showMeTheMoney(){if(!money){return false;}else{...}}
這樣、優(yōu)化后就節(jié)約了25個(gè)字節(jié)、倘若是一個(gè)大的javaScript工程、將節(jié)省出非常大的空間、不但提高了用戶(hù)的下載速度、也減輕了服務(wù)器的壓力。相信這樣的代碼大家見(jiàn)過(guò)不少、很多優(yōu)秀的js插件源碼都這么干!
另外、對(duì)于布爾型的值true和false、true都可以用1來(lái)代替,而false可以用0來(lái)代替。對(duì)于true節(jié)省了3個(gè)字節(jié)、而false則節(jié)省了4個(gè)字節(jié)、例如:
- var bSearch = false;
- for(var i=0;i<aChoices.length&&!bSearch;i++){ if(aChoices[i] == vValue) bSearch = true ; }
替換成:
- var bSearch = 0;
- for(var i=0;i<aChoices.length&&!bSearch;i++){ if(aChoices[i] == vValue) bSearch = 1 ; }
替換了布爾值之后、代碼的執(zhí)行效率、結(jié)果都相同、但節(jié)省了7個(gè)字節(jié)。
代碼中常常會(huì)出現(xiàn)檢測(cè)某個(gè)值是否為有效值的語(yǔ)句、而很多條件非的判斷就判斷某個(gè)變量是否為"undefined"、"null"、或者"false"、例如:
- if(myValue != undefined){ //... } if(myValue !=null){ //... } if(myValue != false){ //... }
這些雖然都正確、但采用邏輯非操作符"!"也可以有同樣的效果、代碼如下:
- if(!myValue){ //... }
這樣的替換也可以節(jié)省一部分字節(jié)、而且不太影響代碼的可讀性。類(lèi)型的代碼優(yōu)化還有將數(shù)組定義時(shí)的 new Array()直接用"[]"代替、對(duì)象定義時(shí)的 new Object()用"{}"代替等、例如:
- var myArray = new Array(); var myArray = []; var myObject = new Object(); var myObject = {};
顯然、第二行和第四行的代碼較為精簡(jiǎn)、而且也很容易理解。
另外、在編寫(xiě)代碼時(shí)往往為了提高可讀性、函數(shù)名稱(chēng)、變量名稱(chēng)使用了很長(zhǎng)的英文單詞、同時(shí)也大大增加了代碼的長(zhǎng)度、例如:
- function AddThreeVarsTogether(firstVar,secondVar,thirdVar){ return (firstVar+secondVar+thirdVar); }
可優(yōu)化成:
- function A(a,b,c){return (a+b+c);}
注意:在進(jìn)行變量名稱(chēng)替換時(shí)、必須十分小心、尤其不推薦使用文本編輯器的"查找"、"替換"功能、因?yàn)榫庉嬈鞑荒芎芎玫貐^(qū)分變量名稱(chēng)或者其他代碼。例如、希望將變量"tion"全部替換成"io"、很可能導(dǎo)致關(guān)鍵字"function"也被破壞。
對(duì)于上面說(shuō)的這些減少代碼體積的方法、有一些很實(shí)用的小工具可以自動(dòng)完成類(lèi)似的工作、例如ECMAScript Cruncher、JSMin、Online JavaScript Compressor等。
2、合理聲明變量
減少代碼的體積僅僅只能使得用戶(hù)下載的速度變快、但執(zhí)行程序的速度并沒(méi)有改變。要提高代碼執(zhí)行的效果、還得在各方面做調(diào)整。
在瀏覽器中、JavaScript默認(rèn)的變量范圍是window對(duì)象、也就是全局變量。全局變量只有在瀏覽器關(guān)閉才釋放。而JavaScript也有局部變量、通常在function中執(zhí)行完畢就會(huì)立即被釋放。因此在函數(shù)體中要盡可能使用var關(guān)鍵字來(lái)聲明變量:
- function First(){ a = "" ; //直接使用變量 } function Second(){ alert(a); } First(); Second();
這樣、變量"a"就成為了全局變量、直到頁(yè)面關(guān)閉時(shí)才會(huì)被銷(xiāo)毀、浪費(fèi)了不必要的資源、如果在"a"的前面加上"var"、這樣"a"就成為了當(dāng)前function的局部變量。在執(zhí)行完First()便立即被銷(xiāo)毀。因此、在函數(shù)體中、如果不是特別需要的全局變量、都應(yīng)當(dāng)使用"var"進(jìn)行聲明、從而節(jié)省系統(tǒng)資源。
3、使用內(nèi)置函數(shù)縮短編譯時(shí)間
只要可能、應(yīng)當(dāng)盡量使用JavaScript的內(nèi)置函數(shù)。因?yàn)檫@些內(nèi)置的屬性、方法都是用類(lèi)似C、C++之類(lèi)的言語(yǔ)編譯過(guò)的、運(yùn)行起來(lái)比實(shí)時(shí)編譯的JavaScript快很多。例如計(jì)算指數(shù)函數(shù)、可以自己編寫(xiě):
- <html>
- <head>
- <base href="<%=basePath%>">
- <title>內(nèi)置函數(shù)</title>
- <meta http-equiv="pragma" content="no-cache">
- <meta http-equiv="cache-control" content="no-cache">
- <meta http-equiv="expires" content="0">
- <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
- <meta http-equiv="description" content="This is my page">
- <script type="text/javascript">
- function myPower(iNum,n){
- var iResult = iNum ;
- for(var i=0;i<n;i++)
- iResult *= iNum ;
- return iResult;
- }
- var myDate1 = new Date();
- for(var i=0;i<150000;i++){
- myPower(7,8); //自定義方法 }
- var myDate2 = new Date();
- document.write(myDate2 - myDate1);
- document.write("<br/>");
- myDate1 = new Date();
- for(var i=0;i<150000;i++){
- Math.pow(7,8); //采用系統(tǒng)內(nèi)置方法
- }
- myDate2 = new Date();
- document.write(myDate2 - myDate1);
- </script>
- </head>
- <body>
- </body>
- </html>
我運(yùn)行的結(jié)果是、自定義方法用了15、內(nèi)置方法用了1(不同的計(jì)算機(jī)運(yùn)行速度會(huì)有差別)、這樣就能看出、系統(tǒng)內(nèi)置的方法要快很多。
4、合理書(shū)寫(xiě)if語(yǔ)句。
if語(yǔ)句恐怕是所有代碼中使用最頻繁的、然而很可惜的是它的執(zhí)行效率并不是很高。在用if語(yǔ)句和多個(gè)else語(yǔ)句時(shí)、一定要把最有可能的情況放在第一個(gè)、然后是可能性第二的、依此類(lèi)推。例如預(yù)計(jì)某個(gè)數(shù)值在0~100之間出現(xiàn)的概率最大、則可以這樣安排代碼:
- if(iNum>0&&iNum <100){
- alert("在0和100之間");
- }
- else if(iNum>99&&iNum<200)
- {
- alert("在100和200之間");
- }
- else if(iNum>199&&iNum<300){
- alert("在200和300之間");
- }else
- {
- alert("小于等于0或者大于等于300");
- }
總是將出現(xiàn)概率最多的情況放在前面、這樣就減少了進(jìn)行多次測(cè)試后才能遇到正確條件的情況。當(dāng)然也要盡可能減少使用else if 語(yǔ)句、例如上面的代碼還可以進(jìn)一步優(yōu)化成如下代碼:
- if(iNum>0){
- if(iNum<100){
- alert("在0和100之間");
- }
- else{
- if(iNum<200){
- alert("在100和200之間");
- }
- else{ if(iNum<300){
- alert("在200和300之間");
- }else{
- alert("大于等于300");
- } } } }
- else{ alert("小于等于0");
- }
上面的代碼看起來(lái)比較復(fù)雜、但因?yàn)榭紤]了很多代碼潛在的判斷問(wèn)題、執(zhí)行問(wèn)題、因此執(zhí)行速度要較前面的代碼快。
另外、通常當(dāng)超過(guò)兩種情況時(shí)、最好能夠使用switch語(yǔ)句。經(jīng)常用switch語(yǔ)句代替if語(yǔ)句、可令執(zhí)行速度快甚至10倍。另外、由于case語(yǔ)句可以使用任何類(lèi)型、也大大方便switch語(yǔ)句的編寫(xiě)。
5、最小化語(yǔ)句數(shù)量
腳本找哦個(gè)的語(yǔ)句越少執(zhí)行的時(shí)間就越短、而且代碼的體積也會(huì)相應(yīng)減少。例如使用var定義變量時(shí)可以一次定義多個(gè)、代碼如下:
- var iNum = 365;
- var sColor = "yellow";
- var aMyNum = [8,7,12,3] ;
- var oMyDate = new Date();
上面的多個(gè)定義可以用var關(guān)鍵字一次性定義、代碼如下:
- var iNum = 365, sColor = "yellow" , aMyNum = [8,7,12,3],oMyDate = new Date() ;
同樣在很多迭代運(yùn)算的時(shí)候、也應(yīng)該盡可能減少代碼量、如下兩行代碼:
- var sCar = aCars[i]; i++;
可優(yōu)化成:
- var sCar = aCars[i++];
6、節(jié)約使用DOM
JavaScript對(duì)DOM的處理可能是最耗費(fèi)時(shí)間的操作之一。每次JavaScript對(duì)DOM的操作都會(huì)改變頁(yè)面的表現(xiàn)、并重新渲染整個(gè)頁(yè)面、從而有明顯的時(shí)間消耗。比較快捷的方法就是盡可能不在頁(yè)面進(jìn)行DOM操作、如下例中為ul添加了10個(gè)條目。
- var oUl = document.getElementById("ulItem");
- for(var i=0;i<10;i++){
- var oLi = document.createElement("li");
- oUl.appendChild(oLi);
- oLi.appendChild(document.createTextNode("Item "+i));
- }
以上代碼在循環(huán)中調(diào)用oUl.appendChild(oLi)、每次執(zhí)行這條語(yǔ)句后、瀏覽器就會(huì)重新渲染頁(yè)面、其次給列表添加文本節(jié)點(diǎn)oLi.appendChild(document.createTextNode("Item "+i))、這也會(huì)造成頁(yè)面被重新渲染。因此每次運(yùn)行都會(huì)造成兩次重新渲染頁(yè)面、共20次。
通常應(yīng)當(dāng)盡可能減少DOM的操作、將列表項(xiàng)目在添加文本節(jié)點(diǎn)之后在添加、并合理地使用createDocumentFragment()、代碼如下:
- var oUl = document.getElementById("ulItem");
- var oTemp = document.createDocumentFragment();
- for(var i=0;i<10;i++){ var oLi = document.createElement("li");
- oLi.appendChild(document.createTextNode("Item "+i));
- oTemp.appendChild(oLi);
- }
- oUl.appendChild(oTemp);
到這,關(guān)于JAVASCRIPT的優(yōu)化就給大家介紹完了。希望對(duì)你有幫助。