Pour un de mes projets (voir le projet GitHub BigPictu.re ou bigpicture.js ), je dois potentiellement traiter un très gros conteneur
Je savais qu’il y avait un risque de mauvaise performance avec l’approche simple que j’utilise, mais je ne m’attendais pas à ce qu’il soit principalement présent avec … Chrome uniquement!
Si vous testez cette petite page (voir le code ci-dessous), le panoramique (clic + glisser) sera:
Bien sûr, je pourrais append du code (dans mon projet) pour que lorsque vous zoomez beaucoup, le texte avec une taille de police potentiellement très grande soit masqué. Mais encore, pourquoi Firefox et Internet Explorer le gèrent-ils correctement et non pas Chrome?
Existe-t-il un moyen en JavaScript, HTML ou CSS pour indiquer au navigateur de ne pas essayer de rendre la page entière (qui fait 10 000 pixels de large ici) pour chaque action? (rendre uniquement la fenêtre d’affichage actuelle!)
html, body { overflow: hidden; min-height: 100%; } #container { position: absolute; min-height: 100%; min-width: 100%; } .text { font-family: "Arial"; position: absolute; } Small text Very big text var container = document.getElementById('container'), dragging = false, previousmouse; container.x = 0; container.y = 0; window.onmousedown = function(e) { dragging = true; previousmouse = {x: e.pageX, y: e.pageY}; } window.onmouseup = function() { dragging = false; } window.ondragstart = function(e) { e.preventDefault(); } window.onmousemove = function(e) { if (dragging) { container.x += e.pageX - previousmouse.x; container.y += e.pageY - previousmouse.y; container.style.left = container.x + 'px'; container.style.top = container.y + 'px'; previousmouse = {x: e.pageX, y: e.pageY}; } }
Passer à la position: fixed
semble accélérer les choses.
Utilisez transform
au lieu de top/left
:
container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';
Une démo en direct à jsFiddle .
Mais en combinant les réponses de Teemu et de geert3 – en utilisant la transformation et la position: fixe, le chrome fonctionne beaucoup plus rapidement, même avec de grandes fonts.
Taille maximale des fonts: http://jsfiddle.net/74w7yL0a/
firefox 34 - 2 000 px chrome 39 - 1 000 000 px safari 8 - 1 000 000 px ie 8-11 - 1 431 700 px
En plus de la réponse de Teemu à l’utilisation de translate:
container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';
Que vous devriez également utiliser d’autres préfixes de fournisseur, vous pouvez simplement résoudre ce problème en l’utilisant sur le corps:
height: 100%; width: 100%; position: relative; overflow: hidden;
et ceci sur html:
height: 100%;
Cela désactivera cependant le défilement. Donc, ce que je ferais, c’est d’append un événement mousedown
au corps et d’appliquer ces styles en utilisant une classe css chaque fois que mousedown
est déclenché et de supprimer cette classe sur mouseup
.
La réponse de @Teemus fait presque tout.
Utilisez transform
avec translate3d
au lieu de top/left
.
translate3d
permet une accélération matérielle.
container.style.transform = 'translate3d(' + container.x + 'px, ' + container.y + 'px, 0)';
Une démo en direct à jsFiddle .
J’ai analysé cela et j’ai constaté que le problème d’origine était lié à l’architecture d’affichage de Chrome et à son utilisation des threads d’arrière-plan pour rendre la page.
Si vous voulez avoir un rendu rapide, allez dans chrome: flags, faites défiler jusqu’au paramètre Impl-side painting et définissez “Disabled”, puis redémarrez le navigateur – le mousemove sera lisse.
Ce que j’ai trouvé, c’est que si vous activez le compteur FPS, les FPS rapportés dans ce scénario sont toujours très élevés, même si les performances réelles à l’écran sont très faibles. Mon explication provisoire (n’étant pas un expert en architecture d’affichage Chrome) est que si le thread et l’affichage de l’interface utilisateur se trouvent sur des threads distincts, alors le rendu de la div peut être contesté. même thread, le thread d’interface utilisateur ne peut pas envoyer de messages plus rapidement que le thread d’interface utilisateur ne peut rendre.
Je suggère que cela devrait être classé comme un bug Chrome.
Utilisez display: table
et table-layout:fixed
sur le div ou une table entourant le div. En HTML:
Le modèle de table HTML a été conçu de manière à ce que les agents utilisateurs puissent rendre des tables de manière incrémentielle (c.-à-d. Au fur et à mesure de l’arrivée des lignes), sans devoir attendre toutes les données avant de commencer le rendu.
Pour qu’un agent utilisateur puisse formater une table en une seule fois, les auteurs doivent indiquer à l’agent utilisateur:
Le nombre de colonnes dans la table. Veuillez consulter la section sur le calcul du nombre de colonnes dans un tableau pour savoir comment fournir ces informations. Les largeurs de ces colonnes. Veuillez consulter la section sur le calcul de la largeur des colonnes pour plus de détails sur la manière de fournir ces informations.
Plus précisément, un agent utilisateur peut rendre une table en un seul passage lorsque les largeurs de colonne sont spécifiées à l’aide d’une combinaison d’éléments COLGROUP et COL. Si l’une des colonnes est spécifiée en termes relatifs ou en pourcentage (voir la section sur le calcul de la largeur des colonnes), les auteurs doivent également spécifier la largeur de la table elle-même.
Pour l’affichage incrémentiel, le navigateur a besoin du nombre de colonnes et de leurs largeurs. La largeur par défaut de la table correspond à la taille actuelle de la fenêtre (width = “100%”). Cela peut être modifié en définissant l’atsortingbut width de l’élément TABLE. Par défaut, toutes les colonnes ont la même largeur, mais vous pouvez spécifier des largeurs de colonne avec un ou plusieurs éléments COL avant le démarrage des données de la table.
Le problème restant concerne le nombre de colonnes. Certaines personnes ont suggéré d’attendre la réception de la première ligne de la table, mais cela pourrait prendre beaucoup de temps si les cellules ont beaucoup de contenu. Dans l’ensemble, il est plus judicieux, lorsqu’un affichage incrémentiel est souhaité, de demander aux auteurs de spécifier explicitement le nombre de colonnes dans l’élément TABLE.
Les auteurs ont toujours besoin d’un moyen d’indiquer aux agents utilisateurs d’utiliser un affichage incrémentiel ou de dimensionner automatiquement la table pour l’adapter au contenu de la cellule. En mode de redimensionnement automatique en deux passes, le nombre de colonnes est déterminé par la première passe. En mode incrémental, le nombre de colonnes doit être indiqué en amont (avec les éléments COL ou COLGROUP).
et CSS
17.5.2.1 Disposition de la table fixe
Avec cet algorithme (rapide), la disposition horizontale de la table ne dépend pas du contenu des cellules; cela ne dépend que de la largeur de la table, de la largeur des colonnes et des bordures ou de l’espacement des cellules.
La largeur de la table peut être spécifiée explicitement avec la propriété ‘width’. Une valeur de ‘auto’ (à la fois pour ‘display: table’ et ‘display: inline-table’) signifie utiliser l’algorithme de mise en page automatique des tableaux. Cependant, si la table est une table de niveau bloc (‘display: table’) en stream normal, un UA peut (mais pas obligatoirement) utiliser l’algorithme de 10.3.3 pour calculer une largeur et appliquer une disposition de table fixe même si la largeur spécifiée est ‘auto’.
Les références