上學時,因我年齡最小,個頭也最小,上課時,就像大猩猩堆里的猴一般。如今,這猴偶爾也把最近的一些情況寫在這里。
4.1 JScript性能優化的基本原則 1. 盡可能少地減少執行次數。畢竟對解釋語言來說,每一個執行步驟,都需要和解釋引擎做一次交互。 2. 盡可能使用語言內置的功能,比如串鏈接。 3. 盡可能使用系統提供的API來進行優化。因為這些API是編譯好的二進制代碼,執行效率很高。 4. 書寫最正確的代碼。容錯功能是要付出性能代價的。 4.2 JScript語言本身的優化 4.2.1 變量 1. 盡量使用局部變量。 因為全局變量其實是全局對象的成員,而局部變量在棧上定義,優先查找,性能相對于全局變量要高。
2. 盡量在一個語句中做定義變量和賦值。
3. 省略不必要的變量定義。 如果變量的定義可以被一個常量替代,就直接使用常量。
4. 使用Object語法對對象賦值。 Object的賦值語法在操作復雜對象時效率更高。 例如,可以將下面的代碼:
替換成:
4.2.2 對象緩存 1. 緩存對象查找的中間結果。 因為JavaScript的解釋性,所以a.b.c.d.e,需要進行至少4次查詢操作,先檢查a再檢查a中的b,再檢查b中的c,如此往下。所以如果這樣的表達式重復出現,只要可能,應該盡量少出現這樣的表達式,可以利用局部變量,把它放入一個臨時的地方進行查詢。
2. 緩存創建時間較長的對象。 自定義高級對象和Date、RegExp對象在構造時都會消耗大量時間。如果可以復用,應采用緩存的方式。
4.2.3 字符串操作 1. 使用"+=" 追加字符串,使用"+"來連接字符串。 如果是追加字符串,最好使用s+=anotherStr操作,而不是要使用s=s+anotherStr。 如果要連接多個字符串,應該使用"+",如: s+=a; s+=b; s+=c; 應該寫成 s+=a + b + c;
2. 連接大量的字符串,應使用Array的join方法。 如果是收集字符串,最好使用JavaScript數組緩存,最后使用join方法連接起來,如下:
4.2.4 類型轉換 1. 使用Math.floor()或者Math.round()將浮點數轉換成整型。 浮點數轉換成整型,這個更容易出錯,很多人喜歡使用parseInt(),其實parseInt()是用于將字符串轉換成數字,而不是浮點數和整型之間的轉換,我們應該使用Math.floor()或者Math.round()。對象查找中的問題不一樣,Math是內部對象,所以Math.floor()其實并沒有多少查詢方法和調用的時間,速度是最快的。
2. 自定義的對象,推薦定義和使用toString()方法來進行類型轉換。 對于自定義的對象,如果定義了toString()方法來進行類型轉換的話,推薦顯式調用toString()。因為內部的操作在嘗試所有可能性之后,會嘗試對象的toString()方法嘗試能否轉化為String,所以直接調用這個方法效率會更高。
4.2.5 循環的優化 1. 盡可能少使用for(in)循環。 在JavaScript中,我們可以使用for(;;),while(),for(in)三種循環,事實上,這三種循環中for(in)的效率極差,因為他需要查詢散列鍵,只要可以就應該盡量少用。
2. 預先計算collection的length。 如:將 for (var i = 0; i < collection.length; i++) 替換成: for (var i = 0, len = collection.length; i < len; i++) 效果會更好,尤其是在大循環中。
3. 盡量減少循環內的操作。 循環內的每個操作,都會被放大為循環次數的倍數。所以,大循環內微小的改進,在性能的整體提升上都是可觀的。
4. 使用循環替代遞歸。相比循環,遞歸的效率更差一些。遞歸的優點是在形式上更自然一些。所以,在不影響代碼的維護性的前提下,用循環替代遞歸。
4.2.6 其它方面 1. 盡量使用語言內置的語法。 "var arr = […];"和"var arr = new Array(…);"是等效的,但是前者的效能優于后者。同樣,"var foo = {};"的方式也比"var foo = new Object();"快;"var reg = /../;"要比"var reg=new RegExp()"快。
2. 盡量不要使用eval。使用eval,相當于在運行時再次調用解釋引擎,對傳入的內容解釋運行,需要消耗大量時間。
3. 使用prototype代替closure。 使用closure在性能和內存消耗上都是不利的。如果closure使用量過大,這就會成為一個問題。所以,盡量將: this.methodFoo = function()替換成: MyClass.protoype.methodFoo = function()和closure存在于對象實例之中不同,prototype存在于類中,被該類的所有的對象實例共享。
4. 避免使用with語句。 With語句臨時擴展對象查找的范圍,節省了文字的錄入時間,但付出了更多的執行時間。因為每個給出的名稱都要在全局范圍查找。所以,可以將下面的代碼:
變更為:
4.3 DOM相關 4.3.1 創建DOM節點 相比較通過document.write來給頁面生成內容,找一個容器元素(比如指定一個div或者span)并設置他們的innerHTML效率更高。 而設置innerHTML的方式比通過createElement方法創建節點的效率更高。事實上,設置元素的innerHTML是創建節點效率最高的一種方式。 如果必須使用createElement方法,而如果文檔中存在現成的樣板節點,應該是用cloneNode()方法。因為使用createElement()方法之后,你需要設置多次元素的屬性,使用cloneNode()則可以減少屬性的設置次數。同樣,如果需要創建很多元素,應該先準備一個樣板節點。
4.3.2 離線操作大型的DOM樹 在添加一個復雜的DOM樹時,可以先構造,構造結束后再將其添加到DOM數的適當節點。這能夠節省界面刷新的時間。
同樣,在準備編輯一個復雜的樹時,可以先將樹從DOM樹上刪除,等編輯結束后再添加回來。 4.3.3 對象查詢 使用[""]查詢要比.item()更快。調用.item()增加了一次查詢和函數的調用。 4.3.4 定時器 如果針對的是不斷運行的代碼,不應該使用setTimeout,而應該用setInterval。setTimeout每次要重新設置一個定時器。 4.4 其他 1. 盡量減小文件尺寸。 將JScript文件中無關的空行、空格、注釋去掉,有助于減小JS文件的尺寸,提高下載的時間。(可以通過工具來支持代碼發布) 2. 盡量不要在同一個Page內同時引用JScript和VBScript引擎 3. 將Page內的JScript移入到單獨的JS文件中。 4. 將Page內的JScript放置在Page的最下面,有助于提高頁面的響應速度。 5. 利用cache,減少JScript文件的下載次數 6. 在HTML內書寫JScript文件的URL時,注意統一大小寫。這樣可以利用前面URL緩存的文件。 7. 推薦使用JScript Lint檢查Javascript代碼。畢竟,對JScript引擎來說,最容易理解的JScript代碼,執行的效率也就最高。
Copyright @ 思勤無邪 Powered by: .Text and ASP.NET Theme by: .NET Monster