一、選擇器性能優化建議
1,最快的選擇器:id選擇器和元素標簽選擇器(盡量使用id代替Class)
這是jQuery選擇器的一條黃金法則。jQuery選擇一個元素最快的方法就是用ID來選擇了。
2,使用匈牙利命名法
在變量前加 $ 前綴,便於識別出 jQuery 對象。
// 糟糕 var first=$('#first'); var second=$('#second'); var value=$first.val(); // 建議 - 在 jQuery 對象前加 $ 前綴 var $first = $('#first'); var $second = $('#second'), var value = $first.val();
3,利用強大的鏈式操作
採用jQuery的鏈式操作比緩存選擇器更有效:
$('li.menu-item').on("click", function () { alert('test click'); }).css('display', 'block').css('color', 'red').fadeTo(2, 0.7);
二、優化DOM操作建議
4,緩存jQuery對象
將你經常用的元素緩存起來:
1):
var header = $('#header'); var divs = header.find('div'); var forms = header.find('form');
2):
var header = $('#header'); var menu = header.find('.menu'); // 或者 var menu = $('.menu', header);
5,當要進行DOM插入時,盡可能減少寫入HTML結構的次數, 多在變量内存裡捯飭完了再操作dom。
var menu = ''; for (let i = 1; i < 100; i++) { menu += '' + i + ''; } menu += ''; $('#header').prepend(menu); // 千萬不要這樣做: $('#header').prepend(''); for (var i = 1; i < 100; i++) { $('#menu').append('' + i + ''); }
(1)改動DOM結構開銷很大,因此不要頻繁使用.append()、.insertBefore()和.insetAfter()這樣的方法。
如果要插入多個元素,就先把它們合並,然後再一次性插入。根據測試,合並插入比不合並插入,快了將近10倍。
(2)如果你要對一個DOM元素進行大量處理,應該先用.detach()方法,把這個元素從DOM中取出來,處理完畢以後,再重新插回文档。根據測試,使用.detach()方法比不使用時,快了60%。
(3)如果你要在DOM元素上儲存數據,不要寫成下面這樣:
var elem = $(‘#elem');elem.data(key,value);
而要寫成:
var elem = $(‘#elem');$.data(elem,key,value);
根據測試,後一種寫法要比前一種寫法,快了將近10倍。因爲elem.data()方法是定義在jQuery函數的prototype對象上面的,而$.data()方法是定義jQuery函數上面的,調用的時候不從複雜的jQuery對象上調用,所以速度快得多。
6,使用直接函數,而不要使用與與之等同的函數
爲了獲得更好的性能,你應該使用直接函數如$.ajax(),而不要使用$.get(),$.getJSON(),$.post(),因爲後面的幾個將會調用$.ajax()。
7,採用jQuery的内部函數data()來存儲狀態
不要忘了採用.data()函數來存儲信息:
// $('#head').data('name', 'value'); // 辣雞方法 $.data("#head", 'name', 'value'); // 之後在你的應用中調用: $('#head').data('name');
三、關於優化事件性能的建議
8,推遲到$(window).load
有時候採用$(window).load()比$(document).ready()更快,因爲後者不等所有的DOM元素都下載完之前執行。你應該在使用它之前測試它。
9,使用Event Delegation
當你在一個容器中有許多節點,你想對所有的節點都綁定一個事件,delegation很適合這樣的應用場景。使用Delegation,我們僅需要在父級綁定事件,然後查看哪個子節點(目標節點)觸發了事件。當你有一個很多數據的table的時候,你想對td節點設置事件,這就變得很方便。先獲得table,然後爲所有的td節點設置delegation事件:
$("table").delegate("td", "hover", function(){ $(this).toggleClass("hover");});
10, 使用ready事件的簡寫
如果你想壓縮js插件,節約每一個字節,你應該避免使用$(document).onready()
// 也不要使用 $(document).ready(function (){ // 代碼 }); // 你可以如此簡寫: $(function (){ // 代碼 });
四、測試jQuery
11,jQuery單元測試
測試JavaSript代碼最好的方法就是人來測試。但你可以使用一些自動化的工具如Selenium,Funcunit,QUit,QMock來測試你的代碼(尤其是插件)。
五、其他常用jQuery性能優化建議
12,使用1.9.1版本的jQuery
這個版本庫産生的流量最小, 也實現了常用的功能了。其他版本的jq, 2.2.4也不錯。至於高版本的,還不如用vue了。
13,使用HMTL5 和css3
新的HTML5標準帶來的是更輕巧的DOM結構。更輕巧的結構意味著使用jQuery需要更少的遍歷,以及更優良的載入性能。所以如果可能的話請使用HTML5。
css3在不需要兼容低版本瀏覽器的時候可以考慮其來代替一些動態效果是一個不錯的選擇。
14, 從cdn分布式節點載入jQuery框架庫
這個需要先從cdn網路優化方面說起, 即便用戶不是每次都從服務器拉文档, 那也沒人希望用自己的服務器是反複給新用戶傳輸靜態文档用的, 一般像jq這種庫, 都掛到cdn上。這裡需要注意的是,雖然網上有大量的文章要求大夥使用第三方現成的cdn, 經過筆者測試, 不少cdn夾帶廣告, 搞的網站莫名其妙彈出廣告來。所以還是自己去買cdn服務比較好。
16,壓縮JavaScript
壓縮和最小化你的JavaScript文档。
在線壓縮地址: 傳送門鏈接
壓縮之前,請保证你的代碼的槼範性,否則可能失敗,導致Js錯誤。
17,注意定義jQuery變量的時候添加var關鍵字
這個不僅僅是jQuery,所有javascript開發過程中,都需要注意,請一定不要定義成如下:
$loading = $('#loading'); //這個是全局定義,不知道哪裡位置倒黴引用了相同的變量名,就會鬱悶至死的
18,多用邏輯判斷||或者&&來提速
請勿如下書寫:
if(!$something) { $something = $('#something '); }
這樣書寫性能更好:
$something = $something || $('#something');
19、盡量使用更少的代碼
與其這樣書寫:if(string.length > 0){..}
不如這樣書寫:if(string.length){..}
20、盡量使用.on方法
如果你使用比較新版本的jQuery類庫的話,請使用.on,其它任何方法都是最終使用.on來實現的。
// 糟糕 $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'); })
21, 盡量使用原生的Javascript
如果使用原生的Javascript也可以實現jQuery提供的功能的話,推薦使用原生的javascript來實現。
22, 正確處理循環
循環總是一種比較耗時的操作,如果可以使用複雜的選擇器直接選中元素,就不要使用循環,去一個個辨認元素。
請不要這樣用
$('.data').each(function(){ console.log($(this)); });
請考慮這樣用
var data = $('.data'); for(i=0;i<data.length;i++){ console.log(data[i]); }
23,避免show()和hide()的使用
當頁面上的元素不是很多時,用show和hide看不出什麽問題,元素一多,就不行了
我們可以修改css,這樣會更快
請不要這樣用
$('#temp1').show();$('#temp2').hide();
請考慮這樣用
$('#temp1').css('display','block');$('#temp2').css('display','none');
24,事件的委托處理(Event Delegation)(強調第9條)
$('td').bind('click', function(){ // 通過使用滑動效果,在顯示和隱藏狀態之間切換元素 $(this).toggleClass('click');//進行 slideUp() 和 slideDown() 之間的切換: });
具體的寫法有兩種。第一種是採用.delegate()方法:
$('table').delegate('td', 'click', function(){ $(this).toggleClass('click'); });
第二種是採用.live()方法:慎用 .live()方法(應該說盡量不要使用)
$('table').each(function(){ $('td', this).live('click', function(){ $(this).toggleClass('click'); }); });
這兩種寫法基本等價。唯一的區別在於,.delegate()是當事件冒泡到指定的父元素時觸發,.live()則是當事件冒泡到文档的根元素後觸發,因此.delegate()比.live()稍快一點。此外,這兩種方法相比傳統的.bind()方法還有一個好處,那就是對動態插入的元素也有效,.bind()只對已經存在的DOM元素有效,對動態插入的元素無效。
25,給選擇器一個上下文
jQuery選擇器中有一個這樣的選擇器,它能指定上下文。
jQuery( expression, context ); 通過它,能縮小選擇器在DOM中搜索的範圍,達到節省時間,提高效率。
普通方式:
以下是引用片段:
$('.myDiv')
改進方式:
以下是引用片段:
$('.myDiv' , $("#listItem") )
注意不是:
var content = $('div #content'); // 非常慢,不要使用
26, 熟記技巧
你可能對使用 jQuery 中的方法缺少經驗,一定要查看的文档,可能會有一個更好或更快的方法來使用它。
// 糟糕 $('#id').data(key, value); // 這種方法更搞笑 $.data('#id', key, value);
27,維持代碼的可讀性
伴隨著精簡代碼和使用鏈式的同時,可能帶來代碼的難以閲讀。添加縮緊和換行能起到很好的效果。
在實際開發過程中要保证代碼的可讀性,但是在發布到網上應用環境的時候壓縮下,就是同樣的代碼兩個版本:開發版本和應用版本。