Nous avons dû faire face à un problème similaire sur FoldingText . Au fur et à mesure que le document s'agrandissait, davantage d'éléments de ligne et d'éléments span associés étaient créés. Le moteur du navigateur semblait s'étouffer, et il fallait donc trouver une meilleure solution.
Voici ce que nous avons fait, qui peut ou non être utile à vos fins :
Visualisez la page entière comme un long document, et la fenêtre du navigateur comme l'objectif d'une partie spécifique du long document. Il suffit de montrer la partie qui se trouve dans l'objectif.
La première partie consiste donc à calculer le port de vue visible. (Cela dépend de la façon dont vos éléments sont placés, absolu / fixe / par défaut)
var top = document.scrollTop;
var width = window.innerWidth;
var height = window.innerHeight;
D'autres ressources pour trouver une fenêtre d'affichage plus compatible avec les navigateurs :
Obtenez les dimensions de la fenêtre du navigateur avec JavaScript
Méthode inter-navigateurs pour détecter le scrollTop de la fenêtre du navigateur
Deuxièmement, vous avez besoin d'une structure de données pour savoir quels éléments sont visibles dans cette zone.
Nous avions déjà mis en place un arbre de recherche binaire équilibré pour l'édition de texte, nous l'avons donc étendu pour gérer également les hauteurs de ligne, cette partie a donc été relativement facile pour nous. Je ne pense pas que vous ayez besoin d'une structure de données complexe pour gérer les hauteurs de vos éléments ; un simple tableau ou un objet peut faire l'affaire. Assurez-vous simplement de pouvoir interroger facilement les hauteurs et les dimensions. Maintenant, comment obtenir les données de hauteur pour tous vos éléments ? Une solution très simple (mais coûteuse en calcul pour un grand nombre d'éléments !)
var boundingRect = element.getBoundingClientRect()
Je parle en termes de javascript pur, mais si vous utilisez jQuery $.offset
, $.position
et les méthodes énumérées aquí serait très utile.
Encore une fois, l'utilisation d'une structure de données n'est importante que comme cache, mais si vous voulez, vous pouvez le faire à la volée (bien que, comme je l'ai dit, ces opérations soient coûteuses). Faites également attention à ne pas modifier les styles css et à appeler ces méthodes. Ces fonctions forcent le redessin, donc vous verrez un problème de performance.
Enfin, il suffit de remplacer les éléments hors écran par un seul, disons <div>
élément dont la hauteur est calculée
-
Maintenant, vous avez des points d'appui pour tous les éléments stockés dans votre structure de données, interrogez tous les éléments qui se trouvent dans la structure de données. avant la fenêtre visible.
-
Créer un <div>
avec une hauteur css définie (en pixels) à la somme des hauteurs des éléments.
-
Indiquez le nom de la classe pour que vous sachiez qu'il s'agit d'une division de remplissage.
-
Enlever tous les éléments du dom que ce div couvre
-
insérez ce div nouvellement créé à la place
Répétez l'opération pour les éléments qui se trouvent après la fenêtre visible.
- Recherchez les événements de défilement et de redimensionnement. À chaque défilement, vous devrez revenir à votre structure de données, supprimer les divs de remplissage, créer les éléments qui ont été précédemment supprimés de l'écran et ajouter en conséquence de nouvelles divs de remplissage.
) Il s'agit d'une méthode longue et complexe, mais pour les documents volumineux, elle a permis d'améliorer considérablement nos performances.
en résumé
Je ne suis pas sûr de l'avoir expliqué correctement, mais l'essentiel de cette méthode est :
- Connaître les dimensions verticales de vos éléments
- Connaître le port de la vue défilée
- Représenter tous les éléments hors écran avec un seul div (hauteur égale à la somme des hauteurs de tous les éléments qu'il couvre)
- Vous aurez besoin de deux divs au total à tout moment, l'un pour les éléments situés au-dessus de la fenêtre visible, l'autre pour les éléments situés en dessous.
- Gardez la trace du port d'affichage en écoutant les événements de défilement et de redimensionnement. Recréez les divs et les éléments visibles en conséquence
J'espère que cela vous aidera.
3 votes
Le fait de définir l'affichage à none déclenche la refonte, ce qui est complètement opposé à ce que vous voulez si ce que vous voulez est d'éviter la refonte. Ne rien faire ne déclenche pas de reflux. Le fait de définir la visibilité sur hidden ne déclenche pas non plus le reflux. Cependant, il est beaucoup plus facile de ne rien faire.
3 votes
Vous devez également savoir que votre gestionnaire de fenêtres supprime déjà les pixels invisibles de l'écran pour accélérer l'interaction avec l'interface utilisateur. Si vous le faites vous-même en javascript, vous risquez de ralentir les choses au lieu de les accélérer.
0 votes
@slebetman // Quand je mets display à none, cela déclenche le reflow. C'est vrai. Mais lorsque vous faites défiler la page, cela déclenche également le reflux et le navigateur doit calculer la mise en page pour tous les éléments de la page. Je pensais que le fait de définir display none à certains des éléments de la page aiderait à réduire le temps de calcul de la mise en page.
0 votes
Avec votre 2ème commentaire, je pense que mettre l'affichage à none n'aidera pas.
0 votes
Non, le reflux n'est pas déclenché lorsque vous faites défiler les pages. Le navigateur dessine tous les éléments en même temps, même en dessous de la ligne de défilement.
0 votes
@slebetman // selon phpied.com/rendering-repaint-reflowrelayout-restyle On dirait que c'est le cas
1 votes
Non, ça ne l'est pas. Vous pouvez le vérifier vous-même en compilant firefox ou chrome avec debug activé et en le passant dans un profileur. Le défilement déclenche des repaints, tout défilement dans tous les programmes, même Word ou Notepad, déclenche des repaints. Même le déplacement du pointeur de la souris déclenche des repaints. Mais les repeints sont bon marché - ils ont déjà été optimisés depuis la fin des années 1980 et sont mis en œuvre par le système d'exploitation/gestionnaire de fenêtres lui-même plutôt que par le programme. Le défilement ne déclenche pas le repeint.
0 votes
@slebetman // merci pour la perspicacité. Je vais le vérifier !
1 votes
@slebetman // ah j'ai l'impression que le reflux de défilement provient de paulirish.com/2011/dom-html5-css3-performance vidéo. La vidéo indique que window.scrollBy provoque un reflux. Je me demande pourquoi il le fait alors que le scroll de l'utilisateur ne le fait pas.
0 votes
C'est le ultime script en termes de performances - airbnb.github.io/infinity
0 votes
Aussi, un grand article sur ce sujet - dannysu.com/2012/07/07/infinite-scroll-memory-optimization
0 votes
@Moon J'ai posté une question similaire stackoverflow.com/questions/33340901/ Veuillez partager les informations que vous avez développées.