高性能javascript--編程實踐

- setTimeout()和settimeInterval()傳遞函數而不是字符串做爲參數

引伸:
用setTimeout()方法來模擬setInterval()與setInterval()之間的什麼區別?node

精確度問題?數組

微任務和宏任務問題?promise

macro-task(宏任務):包括總體代碼script,setTimeout,setInterval瀏覽器

micro-task(微任務):Promise,process.nextTick,相似node.js版的"setTimeout",在事件循環的下一次循環中調用 callback 回調函數。dom

同步>異步異步

主任務>微任務>宏任務函數

console.log('script start');

setTimeout(function() {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');

結果:script start, script end, promise1, promise2, setTimeoutcode

console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

結果:同步任務1,7,微任務nextTick和promise.then()6,8,宏任務setTimeout,裏面做爲一個新的內容2,4,3,5,9,11,10,12對象

- 儘可能使用直接量建立對象和數組

// 使用直接量
var obj = {
  name: 'zzz',
  age: 24,
};
var arr = ["nicholas", 50, true];

// 不使用直接量
var obj = new Object();
obj.name = 'zzz';
obj.age = 24;

var arr = new Array();
arr[0] = "nicholas";
arr[1] = 50;
arr[2] = true;

- 避免作重複的工做,當須要檢測瀏覽器的時候,可以使用延遲加載或條件預加載

最多見的重複工做就是瀏覽器探測,基於瀏覽器的功能做分支判斷致使產生大量代碼。生命週期

一個頁面假若有屢次調用 addHandler 函數添加事件,那麼每次瀏覽器都會作判斷,來執行哪個方法。事實上每次的判斷結果都是同樣的。有幾種方法能夠避免。

function addHandler(target, eventType, handler) { 
  if (target.addEventListener) {  // DOM2 Events
    target.addEventListener(eventType, handler, false);
  } else {  // IE
    target.attachEvent('on' + eventType, handler);
  }
}   

addHandler(document, 'click', function() {
  console.log('hello world');
});

方法一:延遲加載

延遲加載,也稱惰性加載,惰性載入等。延遲加載意味着在信息被使用前不會作任何操做:

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);
}    

addHandler(document, 'click', function() {
  console.log('hello world');
});

addHandler(window, 'keydown', function() {
  console.log('key down');
});
//方法在第一個調用的時候,會作一次判斷決定使用哪一種方法去綁定時間處理器,而後原始addHandler會被新的addHandler函數覆蓋,最後一步調用新的函數,並傳入原始參數。隨後每次調用addHandler()都不會再作檢測,由於檢測代碼已經被新的函數覆蓋。

//第一次總會消耗較長的時間,由於需先檢測再調用完成任務。以後會變快。

方法二:條件預加載

條件預加載會在腳本加載期間提早檢測,而不會等到函數被調用:

var addHandler = document.addEventListener ? 
  function(target, eventType, handler) {
    target.addEventListener(eventType, handler, false);
  }:
  function(target, eventType, handler) {
    target.attachEvent('on' + eventType, handler);
  };    

addHandler(document, 'click', function() {
  console.log('hello world');
});
//這個例子就是先檢查 addEventListener()是否存在,而後根據結果指定函數。

//條件預加載確保全部函數調用消耗的時間相同,代價是須要在腳本加載時就檢測。適用於一個函數立刻就要被用到,而且在整個頁面的生命週期中頻繁出現的場景。

- 在作數學計數時,考慮使用直接操做數字的二進制形式的位運算

- js的原始方法比你寫的任何代碼都快,儘可能使用原生方法。

特別是數學運算。內置Math對象的方法。dom運算,querySelector()和querySelectorAll()

Math 對象用於執行數學任務。

使用 Math 的屬性和方法的語法:

var pi_value=Math.PI;
var sqrt_value=Math.sqrt(15);

Math 對象並不像 Date 和 String 那樣是對象的類,所以沒有構造函數 Math(),像 Math.sin() 這樣的函數只是函數,不是某個對象的方法。您無需建立它,經過把 Math 做爲對象使用就能夠調用其全部屬性和方法。
https://www.w3school.com.cn/j...

相關文章
相關標籤/搜索