對(duì)于jQuery性能的一些優(yōu)化建議
不要每次都在循環(huán)中訪問數(shù)組的 length 屬性,應(yīng)在循環(huán)開始之前就將其緩存:
var myLength = myArray.length; for (var i = 0; i < myLength; i++) { // do stuff }
在循環(huán)外執(zhí)行 append 操作
直接操作 DOM 是非常耗費(fèi)性能的,尤其不要在循環(huán)中直接操作 DOM:
// 這樣性能很差 $.each(myArray, function(i, item) { var newListItem = '<li>' + item + '</li>'; $('#ballers').append(newListItem); });// 這樣性能較好
var frag = document.createDocumentFragment();$.each(myArray, function(i, item) {
var newListItem = '<li>' + item + '</li>';
frag.appendChild(newListItem);
});
$('#ballers')[0].appendChild(frag);// 這樣也很好
var myHtml = '';$.each(myArray, function(i, item) {
html += '<li>' + item + '</li>';
});
$('#ballers').html(myHtml);
代碼要保持精煉
避免做重復(fù)的事情。如果你一直在做重復(fù)的事情,那么就可能出問題了:
// 丑 if ($eventfade.data('currently') != 'showing') { $eventfade.stop(); } if ($eventhover.data('currently') != 'showing') { $eventhover.stop(); } if ($spans.data('currently') != 'showing') { $spans.stop(); } // 漂亮?。? var $elems = [$eventfade, $eventhover, $spans]; $.each($elems, function(i,elem) { if (elem.data('currently') != 'showing') { elem.stop(); } });
警惕匿名函數(shù)
匿名函數(shù)滿天飛是很痛苦的事情,它們難以調(diào)試、維護(hù)、測試或者復(fù)用,應(yīng)盡可能的對(duì)函數(shù)命名并將其封裝在對(duì)象中,實(shí)施有效的管理:
// 不好 $(document).ready(function() { $('#magic').click(function(e) { $('#yayeffects').slideUp(function() { // ... }); }); $('#happiness').load(url + ' #unicorns', function() { // ... }); }); // 好 var PI = { onReady : function() { $('#magic').click(PI.candyMtn); $('#happiness').load(PI.url + ' #unicorns', PI.unicornCb); }, candyMtn : function(e) { $('#yayeffects').slideUp(PI.slideCb); }, slideCb : function() { ... }, unicornCb : function() { ... } }; $(document).ready(PI.onReady);
選擇器的優(yōu)化
隨著越來越多的瀏覽器支持 document.querySelectorAll(),選擇器的重?fù)?dān)已經(jīng)慢慢轉(zhuǎn)移給瀏覽器了,但還是有一些技巧需要注意:
優(yōu)先并盡可能地使用 ID 選擇器:
// 快 $('#container div.robotarm'); // 相當(dāng)快 $('#container').find('div.robotarm'); 使用 $.fn.find 的方式更快,因?yàn)樵?$.fn.find 之前的選擇器并沒有使用 jQuery 自帶的 Sizzle 選擇器引擎,而是使用了瀏覽器 document.getElementById() 方法,瀏覽器原生的方法自然更快。 使用組合選擇器時(shí),盡可能使右端更明確,而左端不盡量不明確: // 未優(yōu)化 $('div.data .gonzalez'); // 已優(yōu)化 $('.data td.gonzalez');
盡量在選擇器右端使用 tag.class,而左端盡可能只使用 tag 或者 .class。
避免過度具體:
$('.data table.attendees td.gonzalez'); // 在不影響結(jié)果的情況下盡量刪掉中間多余部分 $('.data td.gonzalez');
簡潔的 DOM 結(jié)構(gòu)也有助于提升選擇器的性能,因?yàn)檫x擇器可能少走幾層彎路去尋找那些元素。
盡量避免使用通配符,任何顯式或隱式的使用通配符,都會(huì)降低選擇器的性能:
$('.buttons > *'); // 極慢 $('.buttons').children(); // 好多了 $('.gender :radio'); // 隱式地使用通配符,慢 $('.gender *:radio'); // 顯式地使用通配符,同上,慢 $('.gender input:radio'); // 嗯,快多了
使用事件代理
事件代理允許將一個(gè)事件綁定到某個(gè)容器上(例如一個(gè)無序列表 ul),而不是綁定到容器內(nèi)所有元素上(例如列表元素 li)。雖說 $.fn.live 和 $.fn.delegate 都是將事件綁定到容器上,但是應(yīng)盡可能是用 $.fn.delegate,畢竟其明確的上下文(相較于 $.fn.live 的上下文是 document)要小得多,避免了很多不必要的過濾。
除了性能方面的提升,如果給綁定了事件的容器內(nèi)添加新元素,那么這些新元素就無須再次綁定事件了,這也是個(gè)優(yōu)點(diǎn)。
// 不好 (如果列表元素非常多,你就悲劇了) $('li.trigger').click(handlerFn); // 好些:使用 $.fn.live 進(jìn)行事件代理 $('li.trigger').live('click', handlerFn); // 最好:使用 $.fn.delegate 進(jìn)行事件代理 // 因?yàn)檫@樣可以明確的指定一個(gè)上下文 $('#myList').delegate('li.trigger', 'click', handlerFn);
將元素從 DOM 卸載出來再操作
DOM 操作是比較慢的,所以應(yīng)盡量避免直接操作 DOM。jQuery 在其 1.4 版中引入了 $.fn.detach 方法,可以將元素從 DOM 中卸載出來然后進(jìn)行操作,操作好了之后再添加到 DOM 中:
var $table = $('#myTable'); var $parent = $table.parent(); $table.detach(); // ... 例如這里給表格添加了很多很多行 $parent.append(table);
使用外部樣式表為大量元素修改樣式
當(dāng)使用 $.fn.css 為超過 20 個(gè)元素修改樣式時(shí),應(yīng)考慮直接在頁面中添加 style 標(biāo)簽,據(jù)說性能可提升 60%。
// 當(dāng)元素少于 20 個(gè)時(shí)使用這個(gè)方法,多余 20 個(gè)時(shí),速度就慢了 $('a.swedberg').css('color', '#asd123'); // 多余 20 個(gè)元素時(shí),應(yīng)考慮直接在頁面中添加 style 標(biāo)簽 $('<style type="text/css">a.swedberg { color : #asd123 }</style>') .appendTo('head');
使用 $.data 替代 $.fn.data
將 $.data 應(yīng)用于 DOM 元素上,比直接在選擇器上調(diào)用 $.fn.data 要快 10 倍。當(dāng)然,前提是要先明白 DOM 元素和 jQuery 結(jié)果集之間的區(qū)別。
// 速度一般 $(elem).data(key,value); // 速度提升 10 倍 $.data(elem,key,value);
別在空元素上浪費(fèi)時(shí)間
jQuery 不會(huì)主動(dòng)告訴你,你正在一個(gè)空白的結(jié)果集上運(yùn)行代碼 – 而且執(zhí)行過程中并未出錯(cuò)。所以有時(shí)候再執(zhí)行代碼之前,需要先判斷一下結(jié)果集是否為空:
// 不好:執(zhí)行了三個(gè)函數(shù)之后 // 才發(fā)現(xiàn)結(jié)果集上沒有任何元素 $('#nosuchthing').slideUp(); // 好 var $mySelection = $('#nosuchthing'); if ($mySelection.length) { $mySelection.slideUp(); } // 最好:增加一個(gè) doOnce 插件 jQuery.fn.doOnce = function(func){ this.length && func.apply(this); return this; } $('li.cartitems').doOnce(function(){ // 這里可以確保結(jié)果集不是空的 });
這種方法特別適用于 jQuery UI 方面,因?yàn)榧词菇Y(jié)果集中不包含任何元素,其開銷也會(huì)很大。
變量的定義
可以在一條語句中定義多個(gè)變量:
// 老掉牙的寫法 var test = 1; var test2 = function() { ... }; var test3 = test2(test); // 新寫法 var test = 1, test2 = function() { ... }, test3 = test2(test);
在自執(zhí)行函數(shù)中,變量甚至可以不用定義:
(function(foo, bar) { ... })(1, 2);
條件判斷
// 土方法 if (type == 'foo' || type == 'bar') { ... } // 較先進(jìn)的方法 if (/^(foo|bar)$/.test(type)) { ... } // 使用對(duì)象查找 if (({ foo : 1, bar : 1 })[type]) { ... }
相關(guān)文章
Jquery插件easyUi表單驗(yàn)證提交(示例代碼)
本篇文章主要是對(duì)Jquery插件easyUi表單驗(yàn)證提交的示例代碼進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2013-12-12基于Jquery實(shí)現(xiàn)鍵盤按鍵監(jiān)聽
本文介紹下,用jquery實(shí)現(xiàn)的滑動(dòng)效果,以及對(duì)鍵盤按鍵進(jìn)行監(jiān)聽的例子,有需要的朋友,可以參考學(xué)習(xí)下2014-05-05使用jQuery Ajax 請(qǐng)求webservice來實(shí)現(xiàn)更簡練的Ajax
以往我們?cè)谧鯽jax時(shí),都要借助于一般處理程序(.ashx)或web服務(wù)(.asmx),并且每一個(gè)請(qǐng)求都要建一個(gè)這樣的文件,非常麻煩,下面我們甩掉ashx和asmx來使用jQuery Ajax 請(qǐng)求webservice來實(shí)現(xiàn)更簡練的Ajax,需要的朋友參考下2016-08-08IE中jquery.form中ajax提交沒反應(yīng)解決方法分享
用jquery form插件,進(jìn)行ajax提交,本來可以用,好好地,突然發(fā)現(xiàn),firefox,opera等可以提交,ie的success函數(shù)運(yùn)行了2012-09-09jquery中關(guān)于bind()方法的使用技巧分享
這篇文章主要給大家分享了jquery中關(guān)于bind()方法的使用技巧,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。2017-03-03jQuery中parentsUntil()方法用法實(shí)例
這篇文章主要介紹了jQuery中parentsUntil()方法用法,實(shí)例分析了parentsUntil()方法的功能、定義及根據(jù)條件查找匹配元素的所有的祖先元素使用技巧,需要的朋友可以參考下2015-01-01