2013-07-17 3 views
1

Bonjour,jquery Sélecteur avec des conditions « attribut » moins de

juste pour ma soif de connaissances que je suis intéressé par la question s'il est possible d'optimiser la fonction simple suivante.

$('.item').each(function(){ 
    var el = $(this); 
    if (el.data('timestamp') < 1374033452) 
     el.addClass('processed'); 
}); 

Il peut arriver que le sélecteur pour « .item » retours plus d'une centaine, dans le pire des cas, voire des milliers d'éléments et ce n'est pas vraiment une très bonne performance. L'horodatage est une valeur unix-timestamp ajoutée à l'attribut de données de chaque .item.

Cordialement,

Dominik

+0

Si l'horodatage est ajouté dans le code HTML, puis en utilisant getAttribute est probablement plus rapide. Mais je ne sais pas si cela pourrait faire une réelle différence. –

+0

Cette question est mieux posée sur CodeReview.SE que sur le code de travail. –

+0

Si vous devez émettre ceci plusieurs fois, il peut être possible de faire en sorte que les évaluations suivantes soient plus rapides. – mvw

Répondre

1

jQuery ajoute beaucoup de frais généraux. Vous pouvez aller plus de dix fois plus vite en utilisant simplement la vanille JS:

var elements = document.getElementsByClassName('item'); 
for (var i=elements.length; i-->0;) { 
    if (elements[i].getAttribute('data-timestamp') < 1374033452) { 
    elements[i].className = 'processed'; 
    } 
} 

(notez que je devais vous pouvez remplacer toutes les classes, pas simplement ajouter)

JSPerf

Mais le problème de performance que vous l'expérience pourrait être plus liée au coût du reflow qu'à la simple exécution de JavaScript. Par exemple, si la classe processed modifie les dimensions de l'élément, cela peut entraîner une grande redistribution. Il est possible qu'il y ait plus de gain à trouver ici que sur le jQuery/JavaScript pur.

+0

+1 pour aller en natif –

+0

@ArunPJohny Je viens de tester sur Firefox (voir [perfs] (http://jsperf.com/jquery-each-vs-filter/2)). Les résultats sont impressionnants et peut-être bizarre ... –

+0

homme qui a l'air génial :) –

1

Vous pouvez essayer quelque chose comme

$('.item').filter(function(){ 
    return $(this).data('timestamp') < 1374033452 
}).addClass('processed'); 

Exemple: Profiling

+1

Serait-ce plus rapide? Je ne vois pas pourquoi. –

+1

@dystroy marginalement selon ce profil http://jsperf.com/jquery-each-vs-filter –

+0

C'est intéressant. Il y a un vrai gain. Cela peut être lié au gros surcoût au début de la fonction addClass. +1 de moi. –

1
$('.item').addClass(function(){ 
    return this.getAttribute('data-timestamp') < 1374033452 ? 'processed' : ''; 
}); 
+0

+1 encore une fois la condition était inversée dans votre cas, maintenant un marginal + 3% http://jsperf.com/jquery-each-vs-filter –

+0

@ArunPJohny - Oh, je n'ai pas remarqué que j'ai inversé la condition, merci. En ce qui concerne la vitesse, c'est tellement marginal que ça n'a pas d'importance, mais je suis surpris que le filtre soit plus rapide que celui-ci en utilisant le getAttribute natif, etc. – adeneo

0

Je ne pense pas que vous pouvez résoudre la première fois, mais les appels suivants, vous pourraient peut-être avec ceci:

$(".item:not('.processed')").each(function(){ 
    var el = $(this); 
    if (el.data('timestamp') < 1374033452) 
     el.addClass('processed'); 
}); 

Mais je ne sais pas si cela correspond à votre usecase.

http://api.jquery.com/not-selector/