Question

Par exemple, le premier élément de code effectuera-t-il une recherche complète à deux reprises ou sera-t-il assez intelligent pour mettre en cache les résultats si aucun changement DOM n'a eu lieu?

if ($("#navbar .heading").text() > "") {
  $("#navbar .heading").hide();
}

et

var $heading = $("#navbar .heading");

if ($heading.text() > "") {
  $heading.hide();
}

Si le sélecteur est plus complexe, j'imagine que c'est un succès non trivial.

Était-ce utile?

La solution

jQuery ne le fait pas, mais il est possible d'assigner des variables dans votre expression, puis de les réutiliser dans des expressions ultérieures. Alors, cachez votre exemple ...

if ((cached = $("#navbar .heading")).text() > "") {
  cached.hide();
}

L’inconvénient est que cela rend le code un peu plus volumineux et difficile à maîtriser.

Autres conseils

Cachez toujours vos sélections!

Il est inutile d'appeler constamment $ (sélecteur) avec le même sélecteur.

Ou presque toujours ... Vous devez généralement conserver une copie en cache de l'objet jQuery dans une variable locale, sauf si vous vous attendez à ce qu'elle change ou si vous n'en avez besoin qu'une seule fois.

var element = $("#someid");

element.click( function() {

  // no need to re-select #someid since we cached it
  element.hide(); 
});

Ce n’est pas vraiment une question de "est-ce?", mais "peut-il?", et non, vous ne pouvez pas, vous avez peut-être ajouté des éléments de correspondance supplémentaires au DOM depuis la dernière exécution de la requête. Cela rendrait le résultat mis en cache obsolète et jQuery n'aurait aucun moyen (raisonnable) de dire autre que d'exécuter à nouveau la requête.

Par exemple:

$('#someid .someclass').show();
$('#someid').append('<div class="someclass">New!</div>');
$('#someid .someclass').hide();

Dans cet exemple, le nouvel élément ajouté ne serait pas masqué s'il y avait une mise en cache de la requête. Il ne masquerait que les éléments révélés précédemment.

Je viens de faire une méthode pour résoudre ce problème:

var cache = {};

function $(s)
{
    if (cache.hasOwnProperty(s))
    {
        return $(cache[s]);
    }

    var e = $(s);

    if(e.length > 0)
    {
        return $(cache[s] = e);
    }

}

Et cela fonctionne comme ceci:

$('div').each(function(){ ... });

Les résultats sont précis, à ma connaissance, sur la base de cette vérification simple:

console.log($('#forms .col.r')[0] === $('#forms .col.r')[0]);

Attention, votre application MooTools ou toute autre bibliothèque utilisant la notation $$ en souffrira.

Je ne le pense pas (même si je n'ai pas envie de lire trois mille cinq cent lignes de code JavaScript pour le moment, pour le savoir, c'est certain).

Cependant, ce que vous faites n'a pas besoin de plusieurs sélecteurs - cela devrait fonctionner:

$("#navbar .heading:not(:empty)").hide();

Semblable à votre approche $$, j'ai créé une fonction (du même nom) qui utilise un modèle de mémorisation pour garder le filtre plus propre et qui représente également un second paramètre de contexte ... comme $$ (".class", "# context"). Cela est nécessaire si vous utilisez la fonction chaînée find () qui survient après le retour de $$; ainsi, il ne sera pas mis en cache seul à moins que vous ne mettiez d'abord en cache l'objet de contexte. J'ai également ajouté un paramètre booléen à la fin (2ème ou 3ème paramètre, selon que vous utilisiez le contexte) pour le forcer à revenir au DOM.

Code:

function $(a, b, c){
    var key;
    if(c){
        key = a + "," + b;
        if(!this.hasOwnProperty(key) || c){
            this[key] = $(a, b);
        }        
    }
    else if(b){
        if(typeof b == "boolean"){  
            key = a;  
            if(!this.hasOwnProperty(key) || b){
                this[key] = $(a);
            }
        }
        else{
            key = a + "," + b;
            this[key] = $(a, b);   
        }            
    }
    else{
        key = a;
        if(!this.hasOwnProperty(key)){
            this[key] = $(a);
        } 
    }
    return this[key]; 
}

Utilisation:

<div class="test">a</div>
<div id="container">
    <div class="test">b</div>
</div>​

<script>
  $(".test").append("1"); //default behavior
  $(".test", "#container").append("2"); //contextual 
  $(".test", "#container").append("3"); //uses cache
  $(".test", "#container", true).append("4"); //forces back to the dome
​
</script>

Je ne crois pas que JQuery mette en cache des sélecteurs, mais que xpath / javascript se cache derrière pour le gérer. Cela dit, vous pouvez utiliser plusieurs optimisations dans vos sélecteurs. voici quelques articles qui couvrent quelques notions de base:

Ce $$ () fonctionne bien - devrait retourner un objet jQuery valide, en aucun cas un objet jamais indéfini.

Faites attention avec ça! Cela devrait / ne peut pas avec les sélecteurs qui peuvent changer dynamiquement, par exemple. en ajoutant des noeuds correspondant au sélecteur ou en utilisant des pseudoclasses.

function $(selector) {
  return cache.hasOwnProperty(selector) 
    ? cache[selector] 
    : cache[selector] = $(selector); 
};

Et $$ pourrait bien être n'importe quel nom de fonction, bien sûr.

Dans son exposé sur Jquery Internals à jQuery Camp 2008, John Resig mentionne que certains navigateurs prennent en charge les événements déclenchés lors de la modification du DOM. Dans ce cas, les résultats de Selctor pourraient être mis en cache.

Il existe un plugin intéressant appelé jQache qui fait exactement cela. Après avoir installé le plugin, je fais généralement ceci:

  

var $$ = $ .q;

Et puis juste

  

$$ ("#navbar .heading"). hide ();

La meilleure partie de tout cela est que vous pouvez également vider votre cache si nécessaire, par exemple:

  

$$ ("#navbar .heading", true) .hide (); // vide le cache et cache le nouveau #navbar .heading (fraîchement trouvé)

Et

  

$$. clear (); // Efface complètement le cache

jsPerf est en panne aujourd'hui, mais cet article suggère que les gains de performances liés à la mise en cache des sélecteurs jQuery seraient minimes.

entrer la description de l'image ici

Cela peut simplement être dû à la mise en cache du navigateur. Le sélecteur testé n'était qu'un identifiant unique. Davantage de tests devraient être effectués pour les sélecteurs plus complexes et les différentes structures de page ...

jQuery Sizzle met automatiquement en cache les dernières fonctions que ont été créés à partir des sélecteurs afin de trouver des éléments DOM. Cependant, les éléments eux-mêmes ne sont pas mis en cache.

  

De plus, Sizzle conserve un cache des dernières fonctions compilées. Le cache a une taille maximale (qui peut être ajustée mais a une valeur par défaut) afin de ne pas générer d’erreurs de mémoire insuffisante lors de l’utilisation de nombreux sélecteurs différents.

$. selectorCache () est utile:

Gist embed:

<script src="https://gist.github.com/jduhls/ceb7c5fdf2ae1fd2d613e1bab160e296.js"></script>

Vérifiez si cela vous aide https://plugins.jquery.com/cache/

Nous avons rencontré cela dans le cadre de notre projet habituel

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top