Maison >interface Web >js tutoriel >Quelques suggestions d'optimisation pour jQuery performance_jquery

Quelques suggestions d'optimisation pour jQuery performance_jquery

WBOY
WBOYoriginal
2016-05-16 15:45:231103parcourir

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');

Essayez d'utiliser tag.class à l'extrémité droite du sélecteur, et utilisez uniquement tag ou .class à l'extrémité gauche si possible.

Évitez d'être trop précis :

$('.data table.attendees td.gonzalez');

// 在不影响结果的情况下尽量删掉中间多余部分
$('.data td.gonzalez');

Une structure DOM concise contribue également à améliorer les performances du sélecteur, car le sélecteur peut faire moins de détours pour trouver ces éléments.

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(){
  // 这里可以确保结果集不是空的
});

Cette approche est particulièrement utile pour les aspects de l'interface utilisateur de jQuery, car la surcharge peut être importante même si le jeu de résultats ne contient aucun élément.


Définition des variables

Plusieurs variables peuvent être définies dans une seule instruction :

// 老掉牙的写法
var test = 1;
var test2 = function() { ... };
var test3 = test2(test);

// 新写法
var test = 1,
  test2 = function() { ... },
  test3 = test2(test);

Dans les fonctions auto-exécutables, les variables n'ont même pas besoin d'être définies :

(function(foo, bar) { ... })(1, 2);

Jugement conditionnel

// 土方法
if (type == 'foo' || type == 'bar') { ... }

// 较先进的方法
if (/^(foo|bar)$/.test(type)) { ... }

// 使用对象查找
if (({ foo : 1, bar : 1 })[type]) { ... }

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn