Heim > Artikel > Web-Frontend > Einige Optimierungsvorschläge für jQuery performance_jquery
Greifen Sie nicht jedes Mal in der Schleife auf die Längeneigenschaft des Arrays zu, sondern speichern Sie sie zwischen, bevor die Schleife beginnt:
var myLength = myArray.length; for (var i = 0; i < myLength; i++) { // do stuff }
Führen Sie den Anhängevorgang außerhalb der Schleife aus
Die direkte Manipulation von DOM ist sehr leistungsintensiv, insbesondere sollten Sie DOM nicht direkt in einer Schleife manipulieren:
// 这样性能很差 $.each(myArray, function(i, item) { var newListItem = '<li>' + item + '</li>'; $('#ballers').append(newListItem); }); <p>// 这样性能较好<br />var frag = document.createDocumentFragment();</p><p>$.each(myArray, function(i, item) {<br /> var newListItem = '<li>' + item + '</li>';<br /> frag.appendChild(newListItem);<br />});<br />$('#ballers')[0].appendChild(frag);</p><p>// 这样也很好<br />var myHtml = '';</p><p>$.each(myArray, function(i, item) {<br /> html += '<li>' + item + '</li>';<br />});<br />$('#ballers').html(myHtml);</p>
Halten Sie den Code prägnant
Vermeiden Sie es, sich wiederholende Dinge zu tun. Wenn Sie weiterhin das Gleiche tun, stimmt möglicherweise etwas nicht:
// 丑 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(); } });
Seien Sie vorsichtig bei anonymen Funktionen
Es ist sehr schmerzhaft, wenn anonyme Funktionen überall herumschwirren. Sie sind schwierig zu debuggen, zu warten, zu testen oder wiederzuverwenden. Sie sollten die Funktionen so oft wie möglich benennen und in Objekte kapseln, um eine effektive Verwaltung zu implementieren:
// 不好 $(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);
Optimierung des Selektors
Da immer mehr Browser document.querySelectorAll() unterstützen, wurde die Last des Selektors langsam auf den Browser verlagert, aber es gibt immer noch einige Tipps, die Sie beachten sollten:
Priorisieren und verwenden Sie ID-Selektoren, wann immer möglich:
// 快 $('#container div.robotarm'); // 相当快 $('#container').find('div.robotarm'); 使用 $.fn.find 的方式更快,因为在 $.fn.find 之前的选择器并没有使用 jQuery 自带的 Sizzle 选择器引擎,而是使用了浏览器 document.getElementById() 方法,浏览器原生的方法自然更快。 使用组合选择器时,尽可能使右端更明确,而左端不尽量不明确: // 未优化 $('div.data .gonzalez'); // 已优化 $('.data td.gonzalez');
Versuchen Sie, tag.class am rechten Ende des Selektors zu verwenden, und verwenden Sie nach Möglichkeit nur tag oder .class am linken Ende.
Vermeiden Sie es, zu spezifisch zu sein:
$('.data table.attendees td.gonzalez'); // 在不影响结果的情况下尽量删掉中间多余部分 $('.data td.gonzalez');
Eine prägnante DOM-Struktur trägt auch dazu bei, die Leistung des Selektors zu verbessern, da der Selektor möglicherweise weniger Umwege benötigt, um diese Elemente zu finden.
Vermeiden Sie die Verwendung von Platzhaltern. Jede explizite oder implizite Verwendung von Platzhaltern verringert die Leistung des Selektors:
$('.buttons > *'); // 极慢 $('.buttons').children(); // 好多了 $('.gender :radio'); // 隐式地使用通配符,慢 $('.gender *:radio'); // 显式地使用通配符,同上,慢 $('.gender input:radio'); // 嗯,快多了
Ereignis-Proxy verwenden
Der Ereignis-Proxy ermöglicht die Bindung eines Ereignisses an einen Container (z. B. eine ungeordnete Liste ul) und nicht an alle Elemente im Container (z. B. das Listenelement li). Obwohl sowohl $.fn.live als auch $.fn.delegate Ereignisse an den Container binden, sollte $.fn.delegate so oft wie möglich verwendet werden, schließlich ist sein klarer Kontext (im Vergleich zum Kontext des $.fn.live-Dokuments). ) ist viel kleiner, wodurch eine Menge unnötiger Filterung vermieden wird.
Wenn Sie einem an ein Ereignis gebundenen Container neue Elemente hinzufügen, wird nicht nur die Leistung verbessert, sondern diese neuen Elemente müssen nicht erneut an das Ereignis gebunden werden, was ebenfalls von Vorteil ist.
// 不好 (如果列表元素非常多,你就悲剧了) $('li.trigger').click(handlerFn); // 好些:使用 $.fn.live 进行事件代理 $('li.trigger').live('click', handlerFn); // 最好:使用 $.fn.delegate 进行事件代理 // 因为这样可以明确的指定一个上下文 $('#myList').delegate('li.trigger', 'click', handlerFn);
Entladen Sie das Element aus dem DOM und bedienen Sie es dann
DOM-Vorgänge sind relativ langsam, daher sollten Sie versuchen, den direkten Betrieb von DOM zu vermeiden. jQuery hat in seiner Version 1.4 die Methode $.fn.detach eingeführt, mit der Elemente aus dem DOM entladen und dann bearbeitet werden können. Nachdem der Vorgang abgeschlossen ist, können sie dem DOM hinzugefügt werden:
var $table = $('#myTable'); var $parent = $table.parent(); $table.detach(); // ... 例如这里给表格添加了很多很多行 $parent.append(table);
Verwenden Sie externe Stylesheets, um Stile für eine große Anzahl von Elementen zu ändern
Wenn Sie $.fn.css verwenden, um Stile für mehr als 20 Elemente zu ändern, sollten Sie erwägen, Stil-Tags direkt zur Seite hinzuzufügen, was angeblich die Leistung um 60 % verbessert.
// 当元素少于 20 个时使用这个方法,多余 20 个时,速度就慢了 $('a.swedberg').css('color', '#asd123'); // 多余 20 个元素时,应考虑直接在页面中添加 style 标签 $('<style type="text/css">a.swedberg { color : #asd123 }</style>') .appendTo('head');
Verwenden Sie $.data anstelle von $.fn.data
Das Anwenden von $.data auf ein DOM-Element ist zehnmal schneller als der Aufruf von $.fn.data direkt im Selektor. Voraussetzung ist natürlich, zunächst den Unterschied zwischen DOM-Elementen und jQuery-Ergebnismengen zu verstehen.
// 速度一般 $(elem).data(key,value); // 速度提升 10 倍 $.data(elem,key,value);
Verschwenden Sie keine Zeit mit leeren Elementen
jQuery teilt Ihnen nicht aktiv mit, dass Sie Code auf einer leeren Ergebnismenge ausführen – und während der Ausführung treten keine Fehler auf. Daher müssen Sie manchmal vor der Ausführung des Codes zunächst feststellen, ob die Ergebnismenge leer ist:
// 不好:执行了三个函数之后 // 才发现结果集上没有任何元素 $('#nosuchthing').slideUp(); // 好 var $mySelection = $('#nosuchthing'); if ($mySelection.length) { $mySelection.slideUp(); } // 最好:增加一个 doOnce 插件 jQuery.fn.doOnce = function(func){ this.length && func.apply(this); return this; } $('li.cartitems').doOnce(function(){ // 这里可以确保结果集不是空的 });
Dieser Ansatz ist besonders nützlich für jQuery-UI-Aspekte, da der Overhead erheblich sein kann, selbst wenn die Ergebnismenge keine Elemente enthält.
Definition von Variablen
Mehrere Variablen können in einer Anweisung definiert werden:
// 老掉牙的写法 var test = 1; var test2 = function() { ... }; var test3 = test2(test); // 新写法 var test = 1, test2 = function() { ... }, test3 = test2(test);
In selbstausführenden Funktionen müssen Variablen nicht einmal definiert werden:
(function(foo, bar) { ... })(1, 2);
Bedingtes Urteil
// 土方法 if (type == 'foo' || type == 'bar') { ... } // 较先进的方法 if (/^(foo|bar)$/.test(type)) { ... } // 使用对象查找 if (({ foo : 1, bar : 1 })[type]) { ... }