討論jQuery和javascript性能的文章並不罕見。然而,本文我計劃總結一些速度方面的技巧和我本人的一些建議,來提高你的jQuery和javascript代碼。好的代碼會帶來速度的提高。快速渲染和響應意味着更好的用戶體驗。css
首先,在腦子裏緊緊記住jQuery就是javascript。這意味着咱們應該採起相同的編碼慣例,風格指南和最佳實踐。html
首先,若是你是一個javascript新手,我建議您閱讀 《JavaScript初學者的最佳實踐》 ,這是一篇高質量的javascript教程,接觸jQuery以前最好先閱讀。前端
當你準備使用jQuery,我強烈建議你遵循下面這些指南:java
DOM遍歷是昂貴的,因此儘可能將會重用的元素緩存。jquery
1
2
3
4
5
6
7
8
9
10
|
// 糟糕
h = $(
'#element'
).height();
$(
'#element'
).css(
'height'
,h-20);
// 建議
$element = $(
'#element'
);
h = $element.height();
$element.css(
'height'
,h-20);
|
jQuery與javascript同樣,通常來講,最好確保你的變量在函數做用域內。web
1
2
3
4
5
6
7
8
9
10
11
|
// 糟糕
$element = $(
'#element'
);
h = $element.height();
$element.css(
'height'
,h-20);
// 建議
var
$element = $(
'#element'
);
var
h = $element.height();
$element.css(
'height'
,h-20);
|
在變量前加$前綴,便於識別出jQuery對象。ajax
1
2
3
4
5
6
7
8
9
10
11
|
// 糟糕
var
first = $(
'#first'
);
var
second = $(
'#second'
);
var
value = $first.val();
// 建議 - 在jQuery對象前加$前綴
var
$first = $(
'#first'
);
var
$second = $(
'#second'
),
var
value = $first.val();
|
將多條var語句合併爲一條語句,我建議將未賦值的變量放到後面。緩存
1
2
3
4
5
6
7
8
9
|
var
$first = $(
'#first'
),
$second = $(
'#second'
),
value = $first.val(),
k = 3,
cookiestring =
'SOMECOOKIESPLEASE'
,
i,
j,
myArray = {};
|
在新版jQuery中,更短的 on(「click」) 用來取代相似 click() 這樣的函數。在以前的版本中 on() 就是 bind()。自從jQuery 1.7版本後,on()?附加事件處理程序的首選方法。然而,出於一致性考慮,你能夠簡單的所有使用 on()方法。cookie
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 糟糕
$first.click(
function
(){
$first.css(
'border'
,
'1px solid red'
);
$first.css(
'color'
,
'blue'
);
});
$first.hover(
function
(){
$first.css(
'border'
,
'1px solid red'
);
})
// 建議
$first.on(
'click'
,
function
(){
$first.css(
'border'
,
'1px solid red'
);
$first.css(
'color'
,
'blue'
);
})
$first.on(
'hover'
,
function
(){
$first.css(
'border'
,
'1px solid red'
);
})
|
通常來講,最好儘量合併函數。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 糟糕
$first.click(
function
(){
$first.css(
'border'
,
'1px solid red'
);
$first.css(
'color'
,
'blue'
);
});
// 建議
$first.on(
'click'
,
function
(){
$first.css({
'border'
:
'1px solid red'
,
'color'
:
'blue'
});
});
|
jQuery實現方法的鏈式操做是很是容易的。下面利用這一點。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 糟糕
$second.html(value);
$second.on(
'click'
,
function
(){
alert(
'hello everybody'
);
});
$second.fadeIn(
'slow'
);
$second.animate({height:
'120px'
},500);
// 建議
$second.html(value);
$second.on(
'click'
,
function
(){
alert(
'hello everybody'
);
}).fadeIn(
'slow'
).animate({height:
'120px'
},500);
|
伴隨着精簡代碼和使用鏈式的同時,可能帶來代碼的難以閱讀。添加縮緊和換行能起到很好的效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// 糟糕
$second.html(value);
$second.on(
'click'
,
function
(){
alert(
'hello everybody'
);
}).fadeIn(
'slow'
).animate({height:
'120px'
},500);
// 建議
$second.html(value);
$second
.on(
'click'
,
function
(){ alert(
'hello everybody'
);})
.fadeIn(
'slow'
)
.animate({height:
'120px'
},500);
|
短路求值是一個從左到右求值的表達式,用 &&(邏輯與)或 || (邏輯或)操做符。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 糟糕
function
initVar($myVar) {
if
(!$myVar) {
$myVar = $(
'#selector'
);
}
}
// 建議
function
initVar($myVar) {
$myVar = $myVar || $(
'#selector'
);
}
|
精簡代碼的其中一種方式是利用編碼捷徑。
1
2
3
4
5
6
7
|
// 糟糕
if
(collection.length > 0){..}
// 建議
if
(collection.length){..}
|
若是你打算對DOM元素作大量操做(連續設置多個屬性或css樣式),建議首先分離元素而後在添加。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 糟糕
var
$container = $(
"#container"
),
$containerLi = $(
"#container li"
),
$element =
null
;
$element = $containerLi.first();
//... 許多複雜的操做
// better
var
$container = $(
"#container"
),
$containerLi = $container.find(
"li"
),
$element =
null
;
$element = $containerLi.first().detach();
//... 許多複雜的操做
$container.append($element);
|
你可能對使用jQuery中的方法缺乏經驗,必定要查看的文檔,可能會有一個更好或更快的方法來使用它。
1
2
3
4
5
6
7
|
// 糟糕
$(
'#id'
).data(key,value);
// 建議 (高效)
$.data(
'#id'
,key,value);
|
正如前面所提到的,DOM遍歷是一項昂貴的操做。典型作法是緩存父元素並在選擇子元素時重用這些緩存元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 糟糕
var
$container = $(
'#container'
),
$containerLi = $(
'#container li'
),
$containerLiSpan = $(
'#container li span'
);
// 建議 (高效)
var
$container = $(
'#container '
),
$containerLi = $container.find(
'li'
),
$containerLiSpan= $containerLi.find(
'span'
);
|
將通用選擇符放到後代選擇符中,性能很是糟糕。
1
2
3
4
5
6
7
|
// 糟糕
$(
'.container > *'
);
// 建議
$(
'.container'
).children();
|
通用選擇符有時是隱式的,不容易發現。
1
2
3
4
5
6
7
|
// 糟糕
$(
'.someclass :radio'
);
// 建議
$(
'.someclass input:radio'
);
|
例如,Id選擇符應該是惟一的,因此沒有必要添加額外的選擇符。
1
2
3
4
5
6
7
8
|
// 糟糕
$(
'div#myid'
);
$(
'div#footer a.myLink'
);
// 建議
$(
'#myid'
);
$(
'#footer .myLink'
);
|
在此強調,ID 選擇符應該是惟一的,不須要添加額外的選擇符,更不須要多個後代ID選擇符。
1
2
3
4
5
6
7
|
// 糟糕
$(
'#outer #inner'
);
// 建議
$(
'#inner'
);
|
新版本一般更好:更輕量級,更高效。顯然,你須要考慮你要支持的代碼的兼容性。例如,2.0版本不支持ie 6/7/8。
關注每一個新版本的廢棄方法是很是重要的並儘可能避免使用這些方法。
1
2
3
4
5
6
7
8
9
10
11
|
// 糟糕 - live 已經廢棄
$(
'#stuff'
).live(
'click'
,
function
() {
console.log(
'hooray'
);
});
// 建議
$(
'#stuff'
).on(
'click'
,
function
() {
console.log(
'hooray'
);
});
// 注:此處可能不當,應爲live能實現實時綁定,delegate或許更合適
|
谷歌的CND能保證選擇離用戶最近的緩存並迅速響應。(使用谷歌CND請自行搜索地址,此處地址以不能使用,推薦jquery官網提供的CDN)。
如上所述,jQuery就是javascript,這意味着用jQuery能作的事情,一樣能夠用原生代碼來作。原生代碼(或?vanilla)的可讀性和可維護性可能不如jQuery,並且代碼更長。但也意味着更高效(一般更接近底層代碼可讀性越差,性能越高,例如:彙編,固然須要更強大的人才能夠)。牢記沒有任何框架能比原生代碼更小,更輕,更高效(注:測試連接已失效,可上網搜索測試代碼)。
鑑於vanilla 和 jQuery之間的性能差別,我強烈建議吸取兩人的精華,使用(可能的話)和jQuery等價的原生代碼。
最後,我記錄這篇文章的目的是提升jQuery的性能和其餘一些好的建議。若是你想深刻的研究對這個話題你會發現不少樂趣。記住,jQuery並不是不可或缺,僅是一種選擇。思考爲何要使用它。DOM操做?ajax?模版?css動畫?仍是選擇符引擎?或許javascript微型框架或jQuery的定製版是更好的選擇。