解讀優(yōu)化 JavaScript 代碼_Xml教程
推薦:如何使初學(xué)者開發(fā)出一個高質(zhì)量的J2EE系統(tǒng)J2EE學(xué)習(xí)者越來越多,J2EE本身技術(shù)不斷在發(fā)展,涌現(xiàn)出各種概念,本文章試圖從一種容易理解的角度對這些概念向初學(xué)者進(jìn)行解釋,以便掌握學(xué)習(xí)J2EE學(xué)習(xí)方向。 首先我們需要知道Java和J2EE是兩個不同概念,Java不只是指一種語言,已經(jīng)代表與微軟不同的另外一個巨
作者: Gregory Baker, GMail 軟件工程師 和 Erik Arvidsson, Google Chrome 軟件工程師
需要的經(jīng)驗: JavaScript 相關(guān)工作知識
客戶端腳本能讓你的應(yīng)用更加地動態(tài)和活躍, 但是瀏覽器對代碼的解析可能造成效率問題, 而這種性能差異在客戶端之間也不盡相同。 這里我們討論和給出一些優(yōu)化你的 JavaScript 代碼的提示和最佳實(shí)踐。
使用字符串
字符串連接操作會對 Internet Explorer 6 和 7 的垃圾收集帶來很大的影響。 盡管這個問題在 Internet Explorer 8 里面得到解決 -- 字符串連接在 IE8 和其它非 IE 瀏覽器(如 Chrome)中稍微更有效率一點(diǎn) -- 如果你的用戶中有很大一部分在使用 Internet Explorer 6 或 7, 你就需要非常注意你構(gòu)建字符串的方式了。
有如下示例代碼:
|
以下為引用的內(nèi)容:
|
比起用連接的方式, 嘗試使用 join():
| 以下為引用的內(nèi)容:
|
相似的, 用連接的方式在條件語句和循環(huán)中構(gòu)建字符串是很低效的. 錯誤的方式:
var fibonacciStr = '前 20 個斐波那契數(shù) ';
for (var i = 0; i < 20; i++) {
fibonacciStr += i + ' = ' + fibonacci(i) + '
';
}
正確的方法:
var strBuilder = ['前 20 個斐波那契數(shù):'];
for (var i = 0; i < 20; i++) {
strBuilder.push(i, ' = ', fibonacci(i));
}
var fibonacciStr = strBuilder.join('');
構(gòu)建通過輔助函數(shù)生成的字符串
通過傳遞字符串構(gòu)建器(可以是數(shù)組或者輔助類)到函數(shù)中構(gòu)建長字符串, 以避免出現(xiàn)存放臨時結(jié)果的字符串.
例如, 假定 buildMenuItemHtml_ 需要用文字串和變量構(gòu)建一個字符串, 并且會在內(nèi)部使用一個字符串構(gòu)建器, 與其使用:
var strBuilder = [];
for (var i = 0; i < menuItems.length; i++) {
strBuilder.push(this.buildMenuItemHtml_(menuItems[i]));
}
var menuHtml = strBuilder.join();
不如用:
var strBuilder = [];
for (var i = 0; i < menuItems.length; i++) {
this.buildMenuItem_(menuItems[i], strBuilder);
}
var menuHtml = strBuilder.join();
定義類的方法
下面的代碼效率不高, 因為每次構(gòu)造 baz.Bar 的實(shí)例時, 都會為 foo 創(chuàng)建一個新函數(shù)和閉包(closure):
baz.Bar = function() {
// 構(gòu)造函數(shù)代碼
this.foo = function() {
// 方法代碼
};
}
推薦的方式為:
baz.Bar = function() {
// 構(gòu)造函數(shù)代碼
};
baz.Bar.prototype.foo = function() {
// 方法代碼
};
用這種方式, 無論構(gòu)造了多少個 baz.Bar 實(shí)例, 只會創(chuàng)建一個函數(shù)給 foo, 同時不會創(chuàng)建任何閉包.
初始化實(shí)例變量
將帶有值類型(非引用的)的初始化值(例如類型為數(shù)字, 布爾值, null, undefined 或字符串的值)的變量聲明/初始化代碼直接放在 prototype 原型中. 這可以避免每次調(diào)用構(gòu)造函數(shù)時不必要地運(yùn)行初始化代碼. (這個方法無法應(yīng)用到初始化值由構(gòu)造器參數(shù)決定或構(gòu)造時狀態(tài)不確定的實(shí)例變量上.)
例如, 比起寫:
foo.Bar = function() {
this.prop1_ = 4;
this.prop2_ = true;
this.prop3_ = [];
this.prop4_ = 'blah';
};
不如寫:
foo.Bar = function() {
this.prop3_ = [];
};
foo.Bar.prototype.prop1_ = 4;
foo.Bar.prototype.prop2_ = true;
foo.Bar.prototype.prop4_ = 'blah';
謹(jǐn)慎地使用閉包(closure)
閉包是 JavaScript 中一個強(qiáng)大而有用的特性; 但是, 它們也有不好的地方, 包括:
- 它們是最常見的內(nèi)存泄漏源頭.
-
創(chuàng)建一個閉包比創(chuàng)建一個沒有閉包的內(nèi)聯(lián)函數(shù)明顯要慢, 比起重用一個靜態(tài)函數(shù)則更慢. 例如:
function setupAlertTimeout() {
var msg = '要顯示的消息';
window.setTimeout(function() { alert(msg); }, 100);
}比下面的代碼慢:
function setupAlertTimeout() {
window.setTimeout(function() {
var msg = '要顯示的消息';
alert(msg);
}, 100);
}更比下面的代碼慢:
function alertMsg() {
var msg = '要顯示的消息';
alert(msg);
}
function setupAlertTimeout() {
window.setTimeout(alertMsg, 100);
} -
他們增加了作用域鏈(scope chain)的層級. 當(dāng)瀏覽器解析屬性時, 作用域鏈的每一個層級都必須被檢查一次. 在下面的例子中:
var a = 'a';
function createFunctionWithClosure() {
var b = 'b';
return function () {
var c = 'c';
a;
b;
c;
};
}
var f = createFunctionWithClosure();
f();當(dāng)
f被調(diào)用時, 引用a比引用b慢, 它們都比引用c要慢.
查看 IE+JScript Performance Recommendations Part 3: JavaScript Code inefficiencies 獲得更多有關(guān)在 IE 中使用閉包的信息.
避免使用 with
在你的代碼中避免使用 with. 它對性能有非常壞的影響, 因為它修改了作用域鏈, 讓查找在其它作用域的變量變得代價高昂.
避免瀏覽器內(nèi)存泄漏
內(nèi)存泄漏對 Web 應(yīng)用而言是個很普遍的問題, 它會帶來嚴(yán)重的性能問題. 當(dāng)瀏覽器的內(nèi)存使用上升時, 你的 Web 應(yīng)用, 連同用戶系統(tǒng)的其他部分, 都會變慢. Web 應(yīng)用最常見的內(nèi)存泄漏原因是: 在 JavaScript 腳本引擎和瀏覽器 DOM 的 C++ 對象實(shí)現(xiàn)間的循環(huán)引用(例如, 在 JavaScript 腳本引擎和 Internet Explorer 的 COM 基礎(chǔ)架構(gòu)間, 或者 JavaScript 引擎和 Firefox 的 XPCOM 基礎(chǔ)架構(gòu)間).
下面是避免內(nèi)存泄漏的一些經(jīng)驗法則:
使用一個事件系統(tǒng)來附加事件處理函數(shù)
最常見的循環(huán)引用模式 [ DOM 元素 --> 事件處理函數(shù) --> 閉包作用域 --> DOM ] 在 這篇 MSDN 的 Blog 文章中討論過了. 為避免這個問題, 可以使用一個經(jīng)過嚴(yán)格測試的事件系統(tǒng)來附件事件處理函數(shù), 例如 Google doctype, Dojo, or JQuery.
另外, 在 IE 中使用內(nèi)聯(lián)(inline)的事件處理函數(shù)會導(dǎo)致另外一類泄漏. 這不是通常的循環(huán)引用泄漏, 而是內(nèi)存中臨時匿名腳本對象的泄漏. 詳情請查看 理解和解決 IE 泄漏模式(Understanding and Solving Internet Explorer Leak Patterns) 的 "DOM 插入順序泄漏模型(DOM Insertion Order Leak Model)" 一節(jié), 另外在 JavaScript Kit 教程 中還有一個例子.
避免使用擴(kuò)展(expando)屬性
擴(kuò)展屬性是附加到 DOM 元素上的任意 JavaScript 屬性, 也是循環(huán)引用的常見原因. 你能夠在使用擴(kuò)展屬性時不導(dǎo)致內(nèi)存泄漏, 但是很容易不小心就引入一個泄漏. 這個泄漏的模式是 [ DOM 元素 --> 擴(kuò)展屬性 --> 中間對象 --> DOM 元素 ]. 最好的方法就是避免使用它們. 如果你要使用它們, 就只使用簡單的值類型. 如果你要非簡單的類型, 那么在不再需要擴(kuò)展屬性時將它設(shè)為空(null). 參見 理解和解決 IE 泄漏模式(Understanding and Solving Internet Explorer Leak Patterns) 中的 "循環(huán)引用(Circular References)" 一節(jié).
分享:解讀自動更新程序的設(shè)計框架概要說明: 自動更新程序主要負(fù)責(zé)從服務(wù)器中獲取相應(yīng)的更新文件,并且把這些文件下載到本地,替換現(xiàn)有的文件。達(dá)到修復(fù)Bug,更新功能的目的。 本文作為更新程序的一個框架性設(shè)計,主要側(cè)重介紹功能和流程。也許在若干年后,我再回顧當(dāng)初自己的設(shè)計,會有另外
- xml創(chuàng)建節(jié)點(diǎn)(根節(jié)點(diǎn)、子節(jié)點(diǎn))
- WML開發(fā)教程之 WAP網(wǎng)站服務(wù)器配置方法
- WMLScript的語法基礎(chǔ)
- 收集的WML Script標(biāo)準(zhǔn)函數(shù)庫
- WML教程之文本框控件Input
- 無線標(biāo)記語言(WML)基礎(chǔ)之WMLScript 基礎(chǔ)
- xml文件的結(jié)構(gòu)解讀
- 關(guān)于XSL - XSL教程
- 選擇模式 - XSL教程 - 2
- XPath入門 - XSL教程 - 3
- 匹配模式 - XSL教程 - 4
- 測試模式 - XSL教程 - 5
- 相關(guān)鏈接:
- 教程說明:
Xml教程-解讀優(yōu)化 JavaScript 代碼
。