本篇文章給大家及分享的是js優化原則 ,內容挺不錯的,有興趣的朋友可以看一下
首先,與其他語言不同,JS的效率很大程度是取決於JS engine的效率。除了引擎實現的優劣外,引擎本身也會為一些特殊的程式碼模式採取一些最佳化的策略。例如FF、Opera和Safari的JS引擎,都對字串的拼接運算(+)做了特別優化。顯然,要獲得最大效率,就必須了解引擎的脾氣,並盡量迎合引擎的口味。所以對於不同的引擎,所做的優化極有可能是背道而馳的。
而如果做跨瀏覽器的web編程,則最大的問題在於IE6(JScript 5.6)!因為在不打hotfix的情況下,JScript引擎的垃圾回收的bug,會導致其在真實應用中的performance跟其他瀏覽器根本不在一個數量級上。因此在這種場合做優化,其實就是為JScript做優化!
所以第一原則就是只需要為IE6(未打補丁的JScript 5.6或更早版本)做最佳化!
如果你的程式已經優化到在IE6下可以接受的效能,那麼基本上在其他瀏覽器上效能就完全沒有問題。
因此,注意我下面講的許多問題在其他引擎上可能完全不同,例如在循環中進行字串拼接,通常認為需要用Array.join的方式,但是由於SpiderMonkey等引擎對字串的「+」運算做了優化,結果使用Array.join的效率反而不如直接用「+」!但是如果考慮IE6,則其他瀏覽器上的這種效率的差異根本不值一提。
JS最佳化與其他語言的最佳化也仍有相同之處。比如說,不要一上來就急吼的做優化,那樣毫無意義。優化的關鍵,仍然是要把精力放在最關鍵的地方,也就是瓶頸上。一般來說,瓶頸總是出現在大規模循環的地方。這倒不是說循環本身有效能問題,而是循環會迅速放大可能存在的效能問題。
所以第二原則就是以大規模循環體為最主要最佳化物件。
以下的最佳化原則,只在大規模循環中才有意義,在循環體之外做這類最佳化基本上是沒有意義的。
目前絕大多數JS引擎都是解釋執行的,而解釋執行的情況下,在所有操作中,函數呼叫的效率是較低的。此外,過深的prototype繼承鏈或多層次引用也會降低效率。在JScript中,10級引用的開銷大致是一次空函數呼叫開銷的1/2。這兩者的開銷都遠大於簡單操作(如四則運算)。
所以第三原則就是盡量避免過多的引用層級和不必要的多次方法呼叫#。
特別要注意的是,有些情況看似屬性訪問,其實就是方法呼叫。例如所有DOM的屬性,其實都是方法。在遍歷一個NodeList的時候,循環條件對於nodes.length的訪問,看似屬性讀取,實際上是等價於函數調用的。而且IE DOM的實作上,childNodes.length每次都是要透過內部遍歷重新計數的。 (My god,但這是真的!因為我測過,childNodes.length的存取時間與childNodes.length的值成正比!)這非常耗費。所以預先把nodes.length存到js變量,當然可以提高遍歷的效能。
同樣是函數調用,用戶自訂函數的效率又遠低於語言內建函數,因為後者是對引擎本地方法的包裝,而引擎通常是c, c++,java寫的。進一步,同樣的功能,語言內建構造的開銷通常又比內建函數呼叫要效率高,因為前者在JS程式碼的parse階段就可以確定和最佳化。
所以第四原則就是盡量使用語言本身的建構與內建構函數#。
這裡有一個例子是高效能的String.format方法。 String.format傳統的實作方式是用String.replace(regex, func),在pattern包含n個佔位符(包括重複的)時,自訂函數func就被呼叫n次。而這個高效能實作中,每次format呼叫所做的只是一次Array.join然後一次String.replace(regex, string)的操作,兩者都是引擎內建方法,而不會有任何自訂函數呼叫。兩次內建方法調用和n次的自訂方法調用,這就是效能上的差異。
同樣是內建特性,性能上還是有差異的。例如在JScript中對於arguments的存取效能就很差,幾乎趕上一次函數呼叫了。因此如果一個可變參數的簡單函數成為效能瓶頸的時候,可以將其內部做一些改變,不要存取arguments,而是透過對參數的明確判斷來處理。
例如:
Java程式碼
#function sum() {
var r = #0## var r = #0
; ####卷 r += arguments[i];
}
return r;
}
##這個sum通常呼叫的時候個數是較少的,我們希望改進它在參數較少時的效能。若改成:
##Java程式碼
switch (arguments.length) { case 1:
return];
2: return arguments[
0###] + arguments[###1## #]; ##################卷##] + arguments[###1###] + arguments[###2###]; ################## ########## # ###4###: ###return### arguments[###0###] + arguments[###1###] + arguments[###2###] + arguments [###3###]; ################## ###default###: ############## #### var r = ###0###; ######################################################################################################################################'for (var i = #0; i 0
; i #0r += arguments[i];
# #return# r;
}
##Java程式碼
(g === undefined) return r;
# ## (var i = 6; i
## }
return r; #o
##} #
就會增加很多(至少快1倍)。
最後是第五原則,也往往是真實應用中最重要的效能障礙,那就是盡量減少不必要的物件建立 #。
本身建立物件是有一定的代價的,但這個代價其實不大。最根本的問題是由於JScript愚蠢之極的垃圾回收調度演算法,導致隨著物件數量的增加,效能嚴重下降(根據微軟的人自己說複雜度是O(n^2) )。
例如我們常見的字串拼接問題,經過我的測試驗證,單純的多次建立字串物件其實根本不是效能差的原因。要命的是物件建立期間的無謂的垃圾回收的開銷。而Array.join的方式,不會創建中間字符串對象,因此就減少了那該死的垃圾回收的開銷。
因此,如果我們可以將大規模物件建立轉換為單一語句,其效能會得到極大的提升!例如透過建構程式碼然後eval——實際上PIES專案中正在根據這個想法來做一個專門的大規模物件產生器…
##了上面就是偶總結的JS優化五大原則。
轉自--------------hax的技術部落格 http://hax.iteye.com/blog/126859
相關推薦:js優化針對IE6.0起作用(詳細整理)_javascript技巧
以上是js優化原則的詳細內容。更多資訊請關注PHP中文網其他相關文章!