Maison >interface Web >js tutoriel >Quelques suggestions d'optimisation pour jQuery performance_jquery
N'accédez pas à la propriété length du tableau à chaque fois dans la boucle, mettez-la en cache avant le début de la boucle :
var myLength = myArray.length; for (var i = 0; i < myLength; i++) { // do stuff }
Effectuer une opération d'ajout en dehors de la boucle
La manipulation directe du DOM est très gourmande en performances, surtout ne manipulez pas directement le DOM en boucle :
// 这样性能很差 $.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>
Gardez le code concis
Évitez de faire des choses répétitives. Si vous continuez à faire la même chose, il se peut que quelque chose ne va pas :
// 丑 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(); } });
Méfiez-vous des fonctions anonymes
Il est très pénible d'avoir des fonctions anonymes qui volent partout. Elles sont difficiles à déboguer, maintenir, tester ou réutiliser. Vous devez nommer les fonctions autant que possible et les encapsuler dans des objets pour mettre en œuvre une gestion efficace :
// 不好 $(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);
Optimisation du sélecteur
Comme de plus en plus de navigateurs prennent en charge document.querySelectorAll(), la charge du sélecteur a lentement été transférée au navigateur, mais il y a encore quelques conseils auxquels il faut prêter attention :Donner la priorité et utiliser les sélecteurs d'ID autant que possible :
// 快 $('#container div.robotarm'); // 相当快 $('#container').find('div.robotarm'); 使用 $.fn.find 的方式更快,因为在 $.fn.find 之前的选择器并没有使用 jQuery 自带的 Sizzle 选择器引擎,而是使用了浏览器 document.getElementById() 方法,浏览器原生的方法自然更快。 使用组合选择器时,尽可能使右端更明确,而左端不尽量不明确: // 未优化 $('div.data .gonzalez'); // 已优化 $('.data td.gonzalez');
Évitez d'être trop précis :
$('.data table.attendees td.gonzalez'); // 在不影响结果的情况下尽量删掉中间多余部分 $('.data td.gonzalez');
Essayez d'éviter d'utiliser des caractères génériques. Toute utilisation explicite ou implicite de caractères génériques réduira les performances du sélecteur :
$('.buttons > *'); // 极慢 $('.buttons').children(); // 好多了 $('.gender :radio'); // 隐式地使用通配符,慢 $('.gender *:radio'); // 显式地使用通配符,同上,慢 $('.gender input:radio'); // 嗯,快多了
Utiliser le proxy d'événement
Le proxy d'événement permet à un événement d'être lié à un conteneur (comme une liste non ordonnée ul), plutôt qu'à tous les éléments du conteneur (comme l'élément de liste li). Bien que $.fn.live et $.fn.delegate lient tous deux des événements au conteneur, $.fn.delegate doit être utilisé autant que possible, après tout, son contexte clair (par rapport au contexte du document $.fn.live ) est beaucoup plus petit, évitant ainsi de nombreux filtrages inutiles.En plus des améliorations de performances, si vous ajoutez de nouveaux éléments à un conteneur lié à un événement, ces nouveaux éléments n'ont pas besoin d'être à nouveau liés à l'événement, ce qui est également un avantage.
// 不好 (如果列表元素非常多,你就悲剧了) $('li.trigger').click(handlerFn); // 好些:使用 $.fn.live 进行事件代理 $('li.trigger').live('click', handlerFn); // 最好:使用 $.fn.delegate 进行事件代理 // 因为这样可以明确的指定一个上下文 $('#myList').delegate('li.trigger', 'click', handlerFn);
Déchargez l'élément du DOM puis faites-le fonctionner
Les opérations DOM sont relativement lentes, vous devriez donc essayer d'éviter d'utiliser directement DOM. jQuery a introduit la méthode $.fn.detach dans sa version 1.4, qui permet de décharger des éléments du DOM puis de les exploiter. Une fois l'opération terminée, ils peuvent être ajoutés au DOM :.
var $table = $('#myTable'); var $parent = $table.parent(); $table.detach(); // ... 例如这里给表格添加了很多很多行 $parent.append(table);
Utiliser des feuilles de style externes pour modifier les styles d'un grand nombre d'éléments
Lorsque vous utilisez $.fn.css pour modifier les styles de plus de 20 éléments, vous devriez envisager d'ajouter des balises de style directement à la page, ce qui améliorerait les performances de 60 %.
// 当元素少于 20 个时使用这个方法,多余 20 个时,速度就慢了 $('a.swedberg').css('color', '#asd123'); // 多余 20 个元素时,应考虑直接在页面中添加 style 标签 $('<style type="text/css">a.swedberg { color : #asd123 }</style>') .appendTo('head');
Utilisez $.data au lieu de $.fn.data
Appliquer $.data à un élément DOM est 10 fois plus rapide que d'appeler $.fn.data directement sur le sélecteur. Bien entendu, le principe est de d'abord comprendre la différence entre les éléments DOM et les jeux de résultats jQuery.
// 速度一般 $(elem).data(key,value); // 速度提升 10 倍 $.data(elem,key,value);
Ne perdez pas de temps sur des éléments vides
jQuery ne vous dira pas activement que vous exécutez du code sur un jeu de résultats vide – et aucune erreur ne se produira lors de l’exécution. Ainsi, parfois, avant d'exécuter le code, vous devez d'abord déterminer si le jeu de résultats est vide :
// 不好:执行了三个函数之后 // 才发现结果集上没有任何元素 $('#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(){ // 这里可以确保结果集不是空的 });
Définition des variables
// 老掉牙的写法 var test = 1; var test2 = function() { ... }; var test3 = test2(test); // 新写法 var test = 1, test2 = function() { ... }, test3 = test2(test);
(function(foo, bar) { ... })(1, 2);
Jugement conditionnel
// 土方法 if (type == 'foo' || type == 'bar') { ... } // 较先进的方法 if (/^(foo|bar)$/.test(type)) { ... } // 使用对象查找 if (({ foo : 1, bar : 1 })[type]) { ... }