儘可能在body結束前才引入jQuery,而不是在head中。javascript
藉助第三方提供的CDN來引入jQuery,同時注意當使用第三方CDN出現問題時,要引入本地的jQuery文件。css
若是在</body>前引入script文件的話,就不用寫document.ready了,由於這時執行js代碼時DOM已經加載完畢了。html
<body> <script src="http://lib.sinaapp.com/js/jquery11/1.8/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="jquery1.8.min.js">\x3C/script>')</script> </body>
高效正確的使用jQuery選擇器是熟練使用jQuery的基礎,而掌握jQuery選擇器須要必定的時間積累,咱們開始學習jQuery時就應該注意選擇器的使用。java
<div id="nav" class="nav"> <a class="home" href="http://www.jquery001.com">jQuery學習網</a> <a class="articles" href="http://www.jquery001.com/articles/">jQuery教程</a> </div>
若是咱們選擇class爲home的a元素時,可使用下邊代碼:jquery
$('.home'); //1 $('#nav a.home'); //2 $('#nav').find('a.home'); //3
方法1,會使jQuery在整個DOM中查找class爲home的a元素,性能可想而知。
方法2,爲要查找的元素添加了上下文,在這裏變爲查找id爲nav的子元素,查找性能獲得了很大提高。
方法3,使用了find方法,它的速度更快,因此方法三最好。
關於jQuery選擇器的性能優先級,ID選擇器快於元素選擇器,元素選擇器快於class選擇器。由於ID選擇器和元素選擇器是原生的JavaScript操做,而類選擇器不是,你們順即可以看下find context 區別,find() children區別。ajax
CSS解析引擎將自右向左計算每一條規則,它從關鍵選擇器開始,自右向左計算每個選擇器,直到發現一個匹配的選擇器,若是沒有找到匹配的選擇器則放棄查找。編程
使用較低層的規則一般更有效率。數組
儘量的具體化的選擇器——ID要比tag更好。瀏覽器
避免沒必要要的冗餘。緩存
一般請狀況下,請保持選擇器簡單明瞭(好比充分使用ID選擇器),儘量的使用關鍵選擇器更具體,不管對JavaScript仍是CSS,這均可以加塊網站的速度。到目前爲止,不管使用哪種瀏覽器,使用ID選擇器和當個類選擇器都是選中元素最快的方式。
Id選擇符應該是惟一的,因此沒有必要添加額外的選擇符。
// 糟糕 $('div#myid'); $('div#footer a.myLink'); // 建議 $('#myid'); $('#footer .myLink');
在此強調,ID 選擇符應該是惟一的,不須要添加額外的選擇符,更不須要多個後代ID選擇符。
// 糟糕 $('#outer #inner'); // 建議 $('#inner');
通用選擇符有時是隱式的,不容易發現。
// 糟糕 $('.someclass :radio'); // 建議 $('.someclass input:radio');
將通用選擇符放到後代選擇符中,性能很是糟糕。
// 糟糕 $('.container > *'); // 建議 $('.container').children();
精簡代碼的其中一種方式是利用編碼捷徑。
// 糟糕 if(collection.length > 0){..} // 建議 if(collection.length){..}
默認狀況下,當把一個選擇器傳遞給jQuery時,它將遍歷整個DOM,jQuery方法還具備一個未充分利用的參數,既能夠將一個上下文參數傳入jQuery,以限制它只搜索DOM中特定的一部分。
//糟糕,會遍歷整個DOM $(".class"); //建議,只搜索#id元素下的class,id指明搜索範圍 $(".class","#id");
jQuery選擇器的性能比較:
$(".class","#id") > $("#id .class") > $(".class")
緩存jQuery對象能夠減小沒必要要的DOM查找,關於這點你們能夠參考下緩存jQuery對象來提升性能。
// 糟糕 h = $('#element').height(); $('#element').css('height',h-20); // 建議 $element = $('#element'); h = $element.height(); $element.css('height',h-20);
正如前面所提到的,DOM遍歷是一項昂貴的操做。典型作法是緩存父元素並在選擇子元素時重用這些緩存元素。
// 糟糕 var $container = $('#container'), $containerLi = $('#container li'), $containerLiSpan = $('#container li span'); // 建議 (高效) var $container = $('#container '), $containerLi = $container.find('li'), $containerLiSpan= $containerLi.find('span');
jQuery與javascript同樣,通常來講,最好確保你的變量在函數做用域內。
// 糟糕 $element = $('#element'); h = $element.height(); $element.css('height',h-20); // 建議 var $element = $('#element'); var h = $element.height(); $element.css('height',h-20);
在變量前加$前綴,便於識別出jQuery對象。
// 糟糕 var first = $('#first'); var second = $('#second'); var value = $first.val(); // 建議 - 在jQuery對象前加$前綴 var $first = $('#first'); var $second = $('#second'), var value = $first.val();
將多條var語句合併爲一條語句,我建議將未賦值的變量放到後面。
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()方法。
<table id="t"> <tr> <td>我是單元格</td> </tr> </table>
好比咱們要在上邊的單元格上綁定一個單擊事件,不注意的朋友可能隨手寫成下邊的樣子:
$('#t').find('td').on('click', function () { $(this).css({ 'color': 'red', 'background': 'yellow' }); });
這樣會爲每一個td綁上事件,在爲100個單元格綁定click事件的測試中,二者性能相差7倍之多,好的作法應該是下邊寫法:
$('#t').on('click', 'td', function () { $(this).css({ 'color': 'red', 'background': 'yellow' }); });
如在上述代碼中咱們對jQuery代碼進行了適當的合併,相似的還有.attr()方法等,咱們沒有寫成下邊的方式:
$('#t').on('click', 'td', function () { $(this).css('color', 'red').css('background', 'yellow'); });
通常來講,最好儘量合併函數。
// 糟糕 $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實現方法的鏈式操做是很是容易的。下面利用這一點。
// 糟糕 $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);
剛開始使用jQuery時可能會頻繁的操做DOM,這是至關耗費性能的。如咱們要在body中動態輸出一個表格,一些朋友會這樣寫:
//糟糕 var $t = $('body'); $t.append('<table>'); $t.append('<tr><td>1</td></tr>'); $t.append('</table>'); //建議 $('body').append('<table><tr><td>1</td></tr></table>');
這樣在拼接完table串後再添加到body中,對DOM的操做只需一次。羣裏之前有朋友就由於這個致使在IE下輸出時出現問題,而關於字符串的拼接能夠參考下最快建立字符串的方法。
若是你打算對DOM元素作大量操做(連續設置多個屬性或css樣式),建議首先分離元素而後在添加。
// 糟糕 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);
重佈局和重繪是WEB頁面中最多見的也是最昂貴的兩種操做。
當改變樣式,而不改變頁面幾何佈局時,將會發生重繪。隱藏一個元素或者改變一個元素的背景色時都將致使一次重繪。
當對頁面結構進行更新時,將致使頁面重佈局。
//糟糕 for(var i=0; i<10000; i++){ $("#main table").append("<tr><td>aaaa</td></tr>"); } //建議 var tablerow = ""; for(var i=0; i<10000; i++){ tablerow += "<tr><td>aaaa</td></tr>"; } $("#main table").append(tablerow);
伴隨着精簡代碼和使用鏈式的同時,可能帶來代碼的難以閱讀。添加縮緊和換行能起到很好的效果。
// 糟糕 $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);
短路求值是一個從左到右求值的表達式,用 &&(邏輯與)或 ||(邏輯或)操做符。
// 糟糕 function initVar($myVar) { if(!$myVar) { $myVar = $('#selector'); } } // 建議 function initVar($myVar) { $myVar = $myVar || $('#selector'); }
新版本一般更好:更輕量級,更高效。顯然,你須要考慮你要支持的代碼的兼容性。例如,2.0版本不支持ie 6/7/8。
摒棄棄用方法
關注每一個新版本的廢棄方法是很是重要的並儘可能避免使用這些方法。
// 糟糕 - live 已經廢棄 $('#stuff').live('click', function() { console.log('hooray'); }); // 建議 $('#stuff').on('click', function() { console.log('hooray'); }); // 注:此處可能不當,應爲live能實現實時綁定,delegate或許更合適
最後,我記錄這篇文章的目的是提升jQuery的性能和其餘一些好的建議。若是你想深刻的研究對這個話題你會發現不少樂趣。記住,jQuery並不是不可或缺,僅是一種選擇。思考爲何要使用它。DOM操做?ajax?模版?css動畫?仍是選擇符引擎?或許javascript微型框架或jQuery的定製版是更好的選擇。
雖然都是陳詞濫調,可是我發現還不能很好得作到上述全部,記錄下來但願本身可以所有作到。
原生函數老是最快的,這點不難理解,在代碼書寫中咱們不該該忘記原生JS。
就先總結這幾條吧,每條建議並不難理解,但總結全面的話仍是要花費很多時間的。如在減小代碼段中,若是須要根據條件從數組中獲得新數組時,可使用$.grep() 方法,若是你在使用jQuery時有本身心得的話,歡迎在留言中和你們分享!
參考資料:
《jQuery高級編程》[Cesar Otero,Rob Larsen],(譯)施宏斌,清華大學出版社,2013年4月第1版
http://mp.weixin.qq.com/s?__b...