標籤:
避免雙重求值
有四個標準函數可以允許你傳入代碼的字串,然後它才你動態執行。它們分別是:eval、Function、setTimeout、setInterval
事實上當你在javascript代碼中執行另外一段javascript代碼時,都會導致雙重求值的效能消耗,所以在大多數情況下,沒必要使得eval和Function函數,因此最好避免使用它們。至於setTimeout和setInterval,建議傳入函數而不是字串來作為第一個參數
現在Safari4和chrome的javaScript引擎會緩衝住那些使用了eval且重複啟動並執行代碼,這也是一個效能提升點。
使用Object/Array直接量
使用直接量的兩大好處
- 運行速度更快
- 節省代碼量、減少檔案尺寸(事實上對象屬性或者數組項數量越多,使用直接量的好處就越明顯)
不要重複工作
有兩種方法避免重複工作
- 消極式載入
- 條件預先載入
以一個例子來說明吧
function addHandler(target,eventType,handler) { if (target.addEventListener) {//DOM2 Events target.addEventListener(eventType, handler, false); } else {//IE target.attachEvent(‘on‘ + eventType, handler); } } function removeHandler(target, eventType, handler) { if (target.removeEventListener) {//DOM2 Events target.removeEventListener(eventType, handler, false); } else {//IE target.detachEvent(‘on‘ + eventType, handler); } }
事實上頁面一載入,你就知道使用者是使用的哪種瀏覽器,但是這時候如果頁面上有100個元素需要添加事件綁定就需要判斷100次(而本身事實上你只需要去判斷一次)
下面使用消極式載入的方式來試試
function addHandler(target, eventType, handler) { if (target.addEventListener) {//DOM2 Events addHandler = function (target, eventType, handler) { target.addEventListener(eventType, handler, false); } } else {//IE addHandler = function (target, eventType, handler) { target.attachEvent(‘on‘ + eventType, handler); } } addHandler(target, eventType, handler);//調用新的函數 } function removeHandler(target, eventType, handler) { if (target.removeEventListener) {//DOM2 Events removeHandler = function (target, eventType, handler) { target.removeEventListener(eventType, handler, false); } } else {//IE removeHandler = function (target, eventType, handler) { target.detachEvent(‘on‘ + eventType, handler); } } removeHandler(target, eventType, handler);//調用新的函數 }
調用消極式載入函數時,第一次會相對慢些,後面每次調用時都會很快,所以當一個函數在頁面中不會立即調用時,消極式載入是最好的選擇
另外一種方式是使用條件預先載入:會在指令碼載入期間提單檢測,而不會等到函數被調用
var addHandler = document.body.addEventListener ? function (target, eventType, handler) { target.addEventListener(eventType, handler, false); } : function (target, eventType, handler) { target.attachEvent(‘on‘ + eventType, handler); }; var removeHandler = document.body.removeEventListener ? function (target, eventType, handler) { target.removeEventListener(eventType, handler, false); } : function (target, eventType, handler) { target.detachEvent(‘on‘ + eventType, handler); };
位操作
javascript中的數字都是以64位格式進行儲存的,在位操作中,數字被轉換為有符號32位格式,每次運算都是直接操作該32位元得到結果,事實上javascript位操作比其它數學運算和布爾運算操作都要快
舉例來說明一下
1、對2模數,一般性的大家會如下這樣寫
if (i % 2) { //是奇數 } else { //是偶數 }
但下面這樣寫會更快些
if (i & 1) { //是偶數 } else { //是奇數 }
2、位元遮罩(也就是使用單個數位每一位來判定是否選項成立,從而有效把數字轉換為由布爾值標記組成的數組)範例程式碼如下所示
var OPTION_A = 1; var OPTION_B=2; var OPTION_C = 3; var OPTION_D = 4; var options = OPTION_A | OPTION_B | OPTION_C | OPTION_D; if (options&OPTION_A) { //選項a在列表中,進行處理processing } if (options & OPTION_B) { //選項b在列表中,進行處理processing }
使用原生方法
無論你的javascript如何最佳化,都不會比js引擎提供的原生方法更快,原因很簡單這些原生方法在你寫代碼之前就已經存在瀏覽器中了,並且是使用低級語言寫的,這就說明這些代碼已經被編譯成機器碼成為瀏覽器的一部分了,啟能不比你的代碼快?
小結
高效能JavaScript筆記三(編程實踐)