這次帶給大家jQuery程式碼效能優化方法總結,jQuery程式碼效能優化的注意事項有哪些,下面就是實戰案例,一起來看一下。
1、總是用#id去尋找element.
在jQuery中最快的選擇器是ID選擇器($('#someid')) . 這是因為它直接對應為JavaScript的getElementById()方法。
選擇單一元素
<p id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </p>
選擇button的效能不好的一種方式:
var traffic_button = $('#content .button');
取代的是直接選擇button:
var traffic_button = $('#traffic_button');
選擇多個元素
在我們討論選擇多個元素的時候,我們真正需要知道的是DOM的遍歷和循環才是效能低落的原因。為了盡量減少效能損失, 總是使用最近的父ID去尋找。
var traffic_lights = $('#traffic_light input');
2、在Classes前面使用Tags
在jQuery中第二快的選擇器就是Tag選擇器($('head')). 而這是因為它直接對應到JavaScript的getElementsByTagName()方法。
<p id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </p>
總是在一個Class前面加上一個tag名字(記得從一個ID傳下來)
var active_light = $('#traffic_light input.on');
注意:在jQuery裡Class選擇器是最慢的一個選擇器;在IE中它循環整個DOM。可能的話盡量避免使用它。不要在ID前面 加Tags。 例如,它會因為去循環所有的
元素去尋找ID為content的
,而導致很慢。
var content = $('p#content');
按照同樣的思路,從多個ID傳下來是冗餘的。
var traffic_light = $('#content #traffic_light');
3、快取jQuery物件
養成保存jQuery物件到一個變數上(就像上面的例子)的習慣。例如,不要這樣做:
$('#traffic_light input.on).bind('click', function(){...}); $('#traffic_light input.on).css('border', '3px dashed yellow'); $('#traffic_light input.on).css('background-color', 'orange'); $('#traffic_light input.on).fadeIn('slow');
取而代之,首現保存jQuery變數到一個本地變數後,再繼續你的操作。
var $active_light = $('#traffic_light input.on'); $active_light.bind('click', function(){...}); $active_light.css('border', '3px dashed yellow'); $active_light.css('background-color', 'orange'); $active_light.fadeIn('slow');
提示:使用$前輟學表示我們的本地變數是jQuery包集。記住,不要在你的應該程式裡出現一次以上的jQuery重複的選擇操作。額外提示:延遲儲存jQuery物件結果。
如果你想在你的程式的其它地方使用jQuery結果對象(result object(s)),或者你的函數要執行多次,要把它緩存在一個全域範圍的對象裡。透過定義一個全域容器保存jQuery結果對象,就可以在其它的函數裡引用它。
// Define an object in the global scope (i.e. the window object) window.$my ={ // Initialize all the queries you want to use more than once head : $('head'), traffic_light : $('#traffic_light'), traffic_button : $('#traffic_button')}; function do_something(){ // Now you can reference the stored results and manipulate them var script = document.createElement('script'); $my.head.append(script); // When working inside functions, continue to save jQuery results // to your global container. $my.cool_results = $('#some_ul li'); $my.other_results = $('#some_table td'); // Use the global functions as you would a normal jQuery result $my.other_results.css('border-color', 'red'); $my.traffic_light.css('border-color', 'green'); }
4、更好的利用鏈
前面的範例也可以這樣寫:
var $active_light = $('#traffic_light input.on'); $active_light.bind('click', function(){...}) .css('border', '3px dashed yellow') .css('background-color', 'orange') .fadeIn('slow');
這樣可以讓我們寫更少的程式碼,使JavaScript更輕。
5、使用子查詢
jQuery允許我們在一個套件集上附加其它的選擇器。因為我們已經在本地變數裡保存了父物件這樣會減少以後在選擇器上的效能開銷。
<p id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </p>
例如,我們可以利用子查詢快取active和inactive lights以便後面的操作。
var $traffic_light = $('#traffic_light'), $active_light = $traffic_light.find('input.on'), $inactive_lights = $traffic_light.find('input.off');
提示:可以用逗號隔開一次定義多個本地變量,這樣可以節省一些位元組。
6、限制直接對DOM操作
DOM操作的基本做法是在記憶體中建立DOM結構,然後再更新DOM結構。這不是jQuery最好的做法,但對JavaScript來說是高效的。直接操作DOM結構性能是低下的。例如,如果你需要動態建立一列元素,不要這樣做:
var top_100_list = [...], // assume this has 100 unique strings $mylist = $('#mylist'); // jQuery selects our <ul> element for (var i=0, l=top_100_list.length; i<l; i++){ $mylist.append('<li>' + top_100_list[i] + '</li>'); }
取而代之,我們希望在插入DOM結構之前先在一個字串裡建立一套元素。
程式碼
var top_100_list = [...], // assume this has 100 unique strings $mylist = $('#mylist'), // jQuery selects our <ul> element top_100_li = ""; // This will store our list items for (var i=0, l=top_100_list.length; i<l; i++){ top_100_li += '<li>' + top_100_list[i] + '</li>'; } $mylist.html(top_100_li);
更快的做法,在插入DOM結構之前我們應該總是在一個父節點裡包含許多元素
var top_100_list = [...], // assume this has 100 unique strings $mylist = $('#mylist'), // jQuery selects our <ul> element top_100_ul = '<ul id="#mylist">'; // This will store our entire unordered list for (var i=0, l=top_100_list.length; i<l; i++){ top_100_ul += '<li>' + top_100_list[i] + '</li>'; } top_100_ul += '</ul>'; // Close our unordered list $mylist.replaceWith(top_100_ul);
如是你照著上面的做了還是對效能有些迷惑的話,可以參考以下內容:
* 試試jQuery提供的Clone()方法。 Clone()方法建立節點數的拷貝,接著你可以在這個副本中進行操作。
* 使用DOM DocumentFragments. As the creator of jQuery points out, 比直接操作DOM性能上更好. 先創建你需要的結構(就像我們上面用一個字符串做的一樣), 然後使用jQuery的insert or replace methods.
7、事件委托(又名:冒泡事件)
除非特别说明,每一个JavaScript事件(如click, mouseover 等)在DOM结构树上都会冒泡到它的父元素上。如果我们想让很多elements(nodes)调用同一个function这是非常有用的。取而代之的是 你可以只对它们的父级绑定一次,而且可以计算出是哪一个节点触发了事件,而不是绑定一个事件监听器到很多节点上这种效率低下的方式。例如,假如我们要开发 一个包含很多input的大型form,当input被选择的时候我们想绑定一个class name。像这样的帮定是效率低下的:
$('#myList li).bind('click', function(){ $(this).addClass('clicked'); // do stuff });
反而,我们应该在父级侦听click事件。
$('#myList).bind('click', function(e){ var target = e.target, // e.target grabs the node that triggered the event. $target = $(target); // wraps the node in a jQuery object if (target.nodeName === 'LI') { $target.addClass('clicked'); // do stuff } });
父节点担当着发报机的工作,可以在触发了事件的目标element上做一些工作。如果你发现自己把一个event listener帮定到很多个element上,那么你这种做法是不正确的。
8、消除查询浪费
虽然jQuery对没有找到任何匹配的elements处理的很好,但是它还是需要花费时间去查找的。如果你的站点有一个全局的JavaScript,你可能会把每个jQuery function都放在 $(document).ready(function(){ // all my glorious code })里。 不要这样做。只去放一些页面上适合用到的function。这样做最有效的方式是你的模板可以完全控制任何时候或者地方执行JavaScript以内联脚 本的方式初始化function。例如,在你的“article”页面模板里,你可能在body标签关闭之前包含以下代码