10. All services from your imperative.
10
jsPerf ─ http://jsperf.com/
測試片段 Code Snippet 的效能
11. All services from your imperative.
11
理解
Understanding the bottleneck
12. All services from your imperative.
12
Object 與 Array,我該選哪一個?
使用 Object 的時機
無順序的集合
需要用字串當索引的情境
使用 Array 的時機
有順序的陣列
需要用數字當索引的情境
13. All services from your imperative.
13
使用 Object 的技巧
基本原則
使用 建構子函式 (constructor) 建立物件,
不要用 Object.create() 建立物件
不要使用過多的繼承,
減少 prototype chains 的層級
效能評比
Object.create() vs. constructor vs. object literal
http://jsperf.com/object-create-vs-constructor-vs-object-literal/7
14. All services from your imperative.
14
使用 Array 的技巧
基本原則
使用 Array Literals 建立陣列
var a = [1, 2, 3, 4];
在陣列中使用一致的型別 (Type)
陣列索引最好能連貫 (元素之間不要中空)
效能評比
type-inference-performance
http://jsperf.com/type-inference-performance/2
Packed vs. holey arrays
http://jsperf.com/packed-vs-holey-arrays
15. All services from your imperative.
15
優化 JavaScript 記憶體使用效率
提升 Garbage Collector 效率
全域變數不會自動 GC 直到換頁或重載
var myGlobalNamespace = {};
盡量在 function 內使用 var 宣告區域變數
function HelloWorld() {
var str = 'test';
alert(str);
}
16. All services from your imperative.
16
JavaScript 的 Scope 觀念
變數何時會列入 GC 範圍?
function foo() {
var bar = new LargeObject();
bar.someCall();
}
function foo() {
var bar = new LargeObject();
bar.someCall();
return bar;
}
var b = foo();
17. All services from your imperative.
17
JavaScript 的 Scope 觀念
利用匿名函式降低使用全域變數的機會
(function() {
function foo() {
var bar = new LargeObject();
bar.someCall();
return bar;
}
var b = foo();
})();
18. All services from your imperative.
18
使用 window.setTimeout 的注意事項
無法 GC 的情況 ( De-referencing )
var myObj = {
callMeMaybe: function () {
var myRef = this;
var val = setTimeout(function () {
console.log('Time is running
out!');
myRef.callMeMaybe();
}, 1000);
}
};
myObj.callMeMaybe();
myObj = null;
19. All services from your imperative.
19
DOM 快取
http://jsperf.com/each-loop-dom-cache/2
26. All services from your imperative.
26
關於 ”物件”
JavaScript 所有東西都是物件,除了?
undefined
null
string String 物件
number Number 物件
boolean Boolean 物件
基礎型別 (Primitive Type) 的特性
無法在基礎型別上擴增屬性
但可在其上層物件中擴增屬性
27. All services from your imperative.
27
關於 ”物件”
存取屬性的方法
var foo = {name: 'kitten'}
foo.name; // kitten
foo['name']; // kitten
var get = 'name';
foo[get]; // kitten
foo.1234; // SyntaxError
foo['1234']; // works
28. All services from your imperative.
28
關於 ”物件”
刪除屬性的方法
var o = { x: 1 };
delete o.x; // true
o.x; // undefined
重點分析
開發人員應避免在執行時期修改物件結構
如果物件結構沒有異動,JavaScript 引擎會更
容易找到最佳存取路徑
但使用 delete 刪除物件屬性卻會導致最佳化
失效,進而減低物件的操作效率
29. All services from your imperative.
29
關於 ”物件”
指定 null 或 undefined 不會刪除屬性
var o = { x: 1 };
o = null;
o; // null
o.x // TypeError
重點分析
當變數指派為 null 之後,並不是把物件設定
為 NULL,而是將物件指標指向一個 null 物件
這會讓該變數無法進入 GC 狀態,導致記憶
體無法回收
typeof(null) == 'object'
30. All services from your imperative.
30
關於 ”物件”
使用 Object Literal 指定屬性的表示法
var test = {
'case': '使用關鍵字',
delete: '使用關鍵字,但不加上引號' // SyntaxError
};
重點分析
ECMAScript 5 之前,不支援關鍵字命名
也就是 IE6 / IE7 / IE8 這三個版本
只要宣告成 'delete' (字串形式) 就能解決
31. All services from your imperative.
31
關於 ”函式” (Function)
存取上層物件 (this) 的方法
Foo.method = function() {
var that = this;
function test() {
var parent_object = that;
}
test();
}
Foo.method = function() {
(function(that) {
var test = function() {
var parent_object = that;
}
test();
})(this);
}
32. All services from your imperative.
32
結論
JavaScript 效能調校的步驟
量測
理解
調校
別再誤會 JavaScript 了
型別轉換
數字
物件
函式
33. All services from your imperative.
33
參考連結
Writing Fast, Memory-Efficient JavaScript
http://coding.smashingmagazine.com/2012/11/05/writ
ing-fast-memory-efficient-javascript/
JavaScript Garden
http://bonsaiden.github.io/JavaScript-Garden/
JavaScript: The Good Parts
https://www.youtube.com/watch?v=hQVTIJBZook
34. All services from your imperative.
34
聯絡資訊
The Will Will Web
記載著 Will 在網路世界的學習心得與技術分享
http://blog.miniasp.com/
Will 保哥的技術交流中心 (臉書粉絲專頁)
http://www.facebook.com/will.fans
★ ★ ★ Will 保哥的噗浪 ★ ★ ★
http://www.plurk.com/willh/invite