web-dev-qa-db-fra.com

Réponse lente lorsque la table HTML est grande

Je travaille sur une application Web pour la gestion des données de produits, dans laquelle les données de produits sont affichées dans un tableau à 4 colonnes (numéro d'index, SKU, description du produit et stock).

Le problème auquel je suis confronté est que lorsque la table est devenue très grande (> 1000 lignes), la page est très lente, en particulier lorsque je survole une ligne (j'ai défini tr:hover dans le code CSS).

J'ai essayé de résoudre ce problème en affichant partiellement les données et en chargeant davantage lorsque l'utilisateur fait défiler l'écran, en utilisant du javascript:

if (tablesDIV.scrollTop> = tablesDIV.scrollHeight - (tablesDIV.clientHeight + 80)) {
  /*...*/
}

Cela donne de bons résultats, mais cela évite d’atteindre la dernière ligne en appuyant sur Endet lorsqu'un nombre important de lignes est chargé, la page est à nouveau en retard.

Existe-t-il une solution à ce problème?

EDIT: Le code CSS associé à la table.

#tables thead th{border-bottom:1px solid #CCC;background-color:#F5F5F5;background-image:-webkit-gradient(linear,left top,left bottom,from(#F5F5F5),to(#F1F1F1));background-image:-moz-linear-gradient(top,#F5F5F5,#F1F1F1);background-image:-o-linear-gradient(top,#F5F5F5,#F1F1F1);background-image:linear-gradient(top,#F5F5F5,#F1F1F1);font-weight:700;cursor:default}
#tables tbody th{font-weight:700;text-overflow:none}
#tables tbody tr{background:#FFF;cursor:pointer}
#tables tbody tr:nth-child(even){background:#F8F9FC}
#tables tbody tr:hover{background:#CDE}

EDIT2: Démo.

Démo: http://jsfiddle.net/4dpGz/

20
Fong-Wan Chau

La première chose qui ralentit votre boucle est .insertRow(). Vous faites cela en haut de votre boucle, puis vous y ajoutez des cellules. Une fois la ligne ajoutée et chaque cellule ajoutée, le navigateur effectue des calculs de disposition. Utilisez plutôt .createElement(), puis .appendChild() à la fin de votre boucle.

Démo: http://jsfiddle.net/ThinkingStiff/gyaGk/

Remplacer:

row = tableContent.insertRow(i);

Avec:

row = document.createElement('tr');

Et ajoutez ceci à la fin de votre boucle:

tableContent.tBodies[0].appendChild(row);

Cela résoudra votre problème de vitesse de chargement. En ce qui concerne le survol, vous avez trop de règles CSS affectant vos éléments tr et td à l'aide de sélecteurs de balises. J'en ai retiré quelques-uns et utilisé des cours sur quelques-uns, et le survol en survol est beaucoup plus rapide. Plus précisément, j'ai remarqué que overflow: hidden sur les éléments td le ralentissait considérablement. Pensez à combiner certaines de vos règles, à utiliser des sélecteurs plus simples et à ajouter des classes aux éléments pour un traitement CSS plus rapide. En vol stationnaire, de nombreux éléments doivent être recalculés par le moteur de présentation, et moins il y a de règles CSS, mieux c'est. Un exemple que j'ai vu dans votre code était #tables tbody tr alors qu'il n'y avait qu'une seule variable tbody dans la table. #tables tr aurait suffi. Mieux que l'un ou l'autre, c'est une classe. J'ai utilisé .row dans ma démo.

Meilleures pratiques de Google Page Speed ​​

  • Évitez les sélecteurs de descendants: table tbody tr td
  • Évitez les ancêtres redondants: body section article (body jamais nécessaire)
  • Évitez les sélecteurs universels (*): body *
  • Évitez les sélecteurs de balises comme la clé (la plus à droite): ul li
  • Évitez les sélecteurs enfants ou adjacents: ul > li > a
  • Évitez les sélecteurs trop qualifiés: form#UserLogin (# est déjà spécifique)
  • Rendez vos règles aussi spécifiques que possible (classe ou id).
20
ThinkingStiff

En outre, comme dans tout élément HTML chromé, ajouter "transform: rotateX (0deg);" à l'élément de table force l'accélération matérielle à entrer en action, accélérant le défilement de manière significative (si c'est le problème).

5
Javier Guerrero

si votre table a des colonnes régulières (sans colspan et/ou rowspan), vous pouvez améliorer un peu le temps de rendu en appliquant la propriété table-layout:fixed:

MDN: https://developer.mozilla.org/en/CSS/table-layout

Avec la méthode de mise en page "fixe", le tableau entier peut être rendu une fois que la première ligne du tableau a été téléchargée et analysée. Cela peut accélérer le temps de rendu par rapport à la méthode de mise en forme "automatique", mais le contenu de cellule ultérieur peut ne pas tenir dans les largeurs de colonne fournies.

4
fcalderan

Les tableaux doivent être téléchargés et rendus dans leur intégralité avant leur affichage, ce qui semble prendre plus de temps. Cette erreur dépend de la puissance de traitement:

Les grandes tables HTML sont-elles lentes?

Pour le nombre de lignes que vous avez, je suis surpris que vous constatiez un décalage notable, bien que vous puissiez essayer quelques solutions à partir de ce point pour nous aider à vous aider:

  • supprimer les arrière-plans dégradés (tels qu'ils sont rendus par le navigateur)
  • paginer les données de formulaire
  • les lignes de formulaire de sortie en morceaux (par exemple, 200 lignes à la fois)
  • la suppression de tous les css aide-t-elle?
  • spécifier une largeur et une hauteur exactes sur les lignes et les cellules du tableau
2
paulcol.

Si vous travaillez avec de très grandes tables (disons 5000 ou même 500 000 lignes), je vous recommande un petit plugin appelé Clusterize . Vous n'avez même pas besoin de jQuery pour l'utiliser. L'idée est similaire au chargement paresseux d'images, et cela fonctionne extrêmement bien dans la pratique.

2
thdoan

Je trouve que mettre une grande table dans une div, il est préférable d'utiliser un setTimeout. Cela semble accélérer considérablement dans Chrome lors du stockage de la table dans une variable globale avant d'appeler la fonction dans un setTimeout. 

setTimeout("setTable(tdata)",1);

function setTable(d) {
        $("#myDiv").html(d);
}

À la vôtre! B55

0
b55