2009-06-12 7 views
6

Permettez-moi de commencer par m'excuser de ne pas donner d'extrait de code. Le projet sur lequel je travaille est propriétaire et je crains de ne pouvoir montrer exactement sur quoi je travaille. Cependant, je ferai de mon mieux pour être descriptif.Accélération des fonctions jQuery empty() ou replaceWith() lors de la gestion de grands éléments DOM

Voici une ventilation de ce qui se passe dans ma demande:

  1. utilisateur clique sur un bouton
  2. Server récupère une liste d'images sous la forme d'un tableau de données
  3. Chaque ligne de la table contient 8 data-cellules qui à leur tour contiennent chacun un lien hypertexte
    • chaque demande par l'utilisateur peut contenir jusqu'à 50 lignes (I peuvent modifier ce nombre si nécessaire)
    • Cela signifie que la table contient plus de 800 éléments DOM individuels
    • Mon analyse montre que jQuery("#dataTable").empty() et jQuery("#dataTable).replaceWith(tableCloneObject) occupent 97% de mon temps de traitement global et prennent en moyenne 4 à 6 secondes pour terminer.

Je suis à la recherche d'un moyen d'accélérer ou l'autre des fonctions jQuery mentionnées ci-dessus lorsqu'ils traitent avec les éléments DOM massifs qui doivent être enlevés/remplacés. J'espère que mon explication aide.

Répondre

8

jQuery empty() prend beaucoup de temps sur votre table, car il fait une quantité vraiment monumentale de travail avec le contenu de l'élément vide dans l'intérêt de prévenir les fuites de mémoire. Si vous pouvez vivre avec ce risque, vous pouvez ignorer la logique impliquée et faire seulement la partie qui se débarrasse du contenu de la table comme ceci:

while (table.firstChild) 
     table.removeChild(table.firstChild); 

ou

table.children().remove(); 
+0

Cela a fonctionné. Je vais faire plus de travail en ce qui concerne les possibles fuites de mémoire, mais cela a complètement accéléré les choses. Merci tout le monde! –

+0

La première façon a fonctionné, pas la seconde, ce qui me donne encore un débordement de pile sur les grandes tables (50k lignes). – Nico

0

Avez-vous à repeupler tout à la fois, ou pouvez-vous le faire par morceaux sur un setTimeout()? Je me rends compte que cela prendra probablement encore plus de temps en morceaux, mais cela vaut vraiment la peine pour l'utilisateur de voir quelque chose se produire plutôt qu'un blocage apparent.

+0

Tout doit être fait en même temps. –

2

J'ai récemment eu des tables de données très volumineuses qui consommaient 15 secondes à une minute de traitement lorsque des modifications étaient apportées à cause de toutes les manipulations DOM effectuées. Je l'ai descendu à < 1 seconde dans tous les navigateurs, mais IE (il faut 5-10 secondes dans IE8). Le gain de vitesse le plus important que j'ai trouvé a été de supprimer l'élément parent avec lequel je travaillais depuis le DOM, d'effectuer mes modifications, puis de le réinsérer dans le DOM (dans mon cas, le tbody).

Ici, vous pouvez voir les deux lignes de code pertinentes qui m'ont permis d'augmenter considérablement les performances (en utilisant Mootools, mais qui peuvent être portées sur jQuery).

update_table : function(rows) { 
    var self = this; 
    this.body = this.body.dispose(); //<------REMOVED HERE 
    rows.each(function(row) { 
     var active = row.retrieve('active'); 
     self.options.data_classes.each(function(hide, name) { 
      if (row.retrieve(name) == true && hide == true) { 
       active = false; 
      } 
     }); 
     row.setStyle('display', (active ? '' : 'none')); 
     row.store('active', active); 
     row.inject(self.body); //<--------CHANGES TO TBODY DONE HERE 
    }) 
    this.body.inject(this.table); //<-----RE-INSERTED HERE 
    this.rows = rows; 
    this.zebra(); 
    this.cells = this._update_cells(); 
    this.fireEvent('update'); 
}, 
+0

Bon, je peux voir la logique dans tout ça. Cependant, dans mon cas, je suis en train de supprimer une table dans un . On pourrait penser que cela ne prendra pas longtemps, mais la table à l'intérieur de la est ce qui a plus de 800 éléments. Compte tenu de ce scénario, pensez-vous que votre solution proposée fonctionnerait toujours? –

+1

Je fais. Ils introduisent des fragments DOM dans HTML 5 pour résoudre ce problème. Je pense que si vous essayez de tirer sur le , de le mettre à jour et de le remettre en place, vous verrez d'énormes gains de performance. Aussi c'est très simple à faire, j'ai fait le changement avec 2 lignes de code. Si vous avez installé Firebug, vous pouvez utiliser le bouton 'Profil' sous l'onglet 'Console' pour voir où votre performance est en train de manger. – tj111

-1

Ce qui a fonctionné pour moi est $("#myTable").detach() . Je devais effacer une table qui a 1000s de lignes. J'ai essayé $("#myTable").children().remove(). C'était une amélioration par rapport à $("myTable").empty(), mais toujours très lent. $("#myTable").detach() prend 1 seconde ou moins. Fonctionne bien dans FF et Chrome. IE est toujours lent.

Questions connexes