Fork me on GitHub

Programming Design Notes

Javascript 效能最佳化

| Comments

Javascript 使用不同的寫法效能也可能有很大的出入


不使用 eval
因為 Javascript engine 要將字串轉成可執行程式碼
轉換過程一定會有效能損耗
以下的例子可以做出相同的目的
但效能則不一樣


較慢:
function getProperty(oString){
var oReference;
eval('oReference = test.prop.' + oString);
return oReference;
}
較快:
function getProperty(oString){
return test.prop[oString];
}

不使用 with
因為 Javascript engine 要找尋變數的參考位置

較慢:
with (test.object) {
foo = 'Value of foo property of object';
bar = 'Value of bar property of object';
}

較快:
var myObj = test.object;
myObj.foo = 'Value of foo property of object';
myObj.bar = 'Value of bar property of object';

不要在迴圈內使用 try-catch-finally
如果情況許可
應該不用 try-catch-finally 會更好
因為使用 try-catch-finally 時
Javascript engine 會創造出一個變數去處理例外事件 (Exception)
如果在迴圈內使用
Javascript engine 在每一個迴圈也要重新創造出新的變數

較慢:
var object = ['foo', 'bar'], i;
for (i = 0; i < object.length; i++) {
try {
// do something that throws an exception
}
catch (e) {
// handle exception
}
}
較快:
var object = ['foo', 'bar'], i;
try {
for (i = 0; i < object.length; i++) {
// do something
}
}
catch (e) {
// handle exception
}

盡量不使用全域變數

如果全域變數在其他區域內
Javascript engine 需要到變數所在的區域去查找變數
會令效能下降


較慢:
var i, str = '';
function globalScope(){
for (i = 0; i < 100; i++) {
str += i; // here we reference i and str in global scope which is slow
}
}

globalScope();
較快:
function localScope(){
var i, str = '';
for (i = 0; i < 100; i++) {
str += i; // i and str in local scope which is faster
}
}

localScope();

在 for 內盡量不使用 in
因為 Javascript engine 需要先創造出一個列舉
會做成效能損耗

較慢:
var sum = 0;
for (var i in arr) {
sum += arr[i];
}
較快:
var sum = 0;
for (var i = 0, len = arr.length; i < len; i++) {
sum += arr[i];
}

盡量不使用 + 去連接字串 (String)
使用 + 會先將 String 在記憶體內連接完成才放到變數的記憶位於內

較慢:
a += 'x' + 'y';

較快:
a += 'x'; 
a += 'y';

使用 setTimeout 和 setInterval 時不要使用字串 (String)
和 eval 的理由相同
因為 Javascript engine 要將字串轉成可執行程式碼
轉換過程一定會有效能損耗



較慢:
setInterval('doSomethingPeriodically()', 1000);
setTimeOut('doSomethingAfterFiveSeconds()', 5000);

較快:
setInterval(doSomethingPeriodically, 1000);
setTimeOut(doSomethingAfterFiveSeconds, 5000);

變數名稱要盡量簡短

較慢:
function someFunction(){
var person_full_name = "somename"; /* stores the full name*/
}
較快:
function someFunction(){
var name = "somename";
}

將全域變數儲存到區域變數內使用
以上已經提過
查找全域變數一定會比區域變數慢
如果在 function 內需要使用同一個全域變數 2 次或以上
更加要在 function 的開始就將全域變數放到區域變數上

較慢:
function doSomethingElseFaster(){
for (var i = 0; i < 100000; i++) {
document.getElementsByTagName('head');
}
}
較快:
function doSomethingElseFaster(){
var get = document.getElementsByTagName;
for (var i = 0; i < 100000; i++) {
get('head');
}
}

相關書籍: High Performance JavaScriptPro Javascript RIA Techniques: Best Practices, Performance and PresentationEven Faster Web Sites: Performance Best Practices for Web Developers