2009-12-03 11 views
0

Je souhaite appliquer un événement click() à tous les liens d'une page lorsque le lien href de ce lien pointe vers un fichier avec une extension spécifique. La liste des extensions applicables tourne autour de 30 et pourrait augmenter un peu dans le futur (mais ne dépassera jamais 100).À quel point les performances de jQuery se dégradent-elles en cas d'utilisation d'un grand nombre de sélecteurs?

Ma première tendance est de structurer l'événement de liaison comme ceci:

$("a[href$=avi], 
    a[href$=ppt], 
    a[href$=rtf], 

// ...snip a bunch more of these.... 

    a[href$=pdf], 
    a[href$=xml]").click(function() { 
     // Do something 
}); 

Est-ce fou?

Répondre

6

Je sélectionnerait tous les liens et filtrer dans la fonction de clic, par exemple comme ceci:

$('a').click(function() { 
    var ext = /[^.]+$/.exec($(this).attr('href')); 
    switch(ext) { 
     case 'avi': 
     case 'ppt': 
     ... 
     case 'xml': 
      // Do something 
      break; 
    } 
}); 

permet de gagner beaucoup de déplacement et est beaucoup plus joli aussi. La mauvaise chose avec votre approche est que jQuery gère probablement chacun de votre sélecteur indépendamment, donc après avoir terminé la recherche du premier sélecteur, il oublie complètement ce qu'il a trouvé et recherche à nouveau le document entier pour le sélecteur suivant. Avec cette méthode, jQuery doit seulement chercher une fois tous les liens, et l'utilisation de switch-case dans la fonction est probablement si rapide que vous n'avez pas à vous soucier des problèmes de performance.

+0

Cela ajoute un gestionnaire de clic à tous les liens, bien que. C'est juste que ça ne fait rien à moins que les href ne correspondent. Une solution qui applique uniquement le gestionnaire aux liens correspondants serait préférable. Voir mon exemple de filtre. – tvanfosson

+0

@tvanfosson: Vous avez raison de dire que cette méthode fait une liaison inutile, mais dans votre méthode, jQuery doit encore faire un peu plus d'analyse et de déplacement, ce qui est toujours plus lent qu'un switch-case. Donc, la performance sage, cette méthode est meilleure. –

3

Je vais vous donner un indice - presque définitivement. J'ai fait quelque chose comme ça et c'était très douloureux. J'ai essayé une autre approche, le stockage des résultats de chaque sélecteur dans un tableau, puis faire $ (tableau) .cliquez() était beaucoup plus rapide (en particulier dans IE6/P3 900MHz)

Cela dit, vous devriez référence et trouver le moyen le plus rapide pour votre application. Trouvez un vieil ordinateur merdique avec IE6, ou obtenez une VM avec IE6, et testez le timing. Le réglage du sélecteur (et le fait de voir qui sont lents et comment je peux éviter de les appeler) est mon premier arrêt sur l'optimisation de javascript.

+1

+1 pour l'analyse comparative – GloryFish

2

j'envisager d'utiliser une fonction de filtre plutôt que d'un ensemble de sélecteurs:

$('a').filter(function() { 
      return $(this).attr('href').match(/(avi|ppt|...|xml)$/) != null; 
     }) 
     .click(function() { 
      // do something 
     });