Une très, très, très grande div

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:

  • Normal / lisse sur Firefox
  • Normal / lisse même sur Internet Explorer
  • Très lent (presque en panne) sur Chrome!

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 .

  1. Réponse à la première quête “pourquoi”. L’un des problèmes est la taille de la police . vous avez la taille de police 600000px, la plupart des navigateurs le verront comme trop élevé et le rendront plus petit, tandis que le chrome essaiera de rendre la taille d’origine. On dirait que le chrome ne peut pas repeindre de telles lettres avec vos styles demandés très rapidement.

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.

  1. Réponse à la deuxième question: “Y a-t-il un moyen … de ne pas essayer de rendre la page entière” – vous pouvez essayer d’appliquer une action de la souris pour les éléments du conteneur, pas pour le conteneur entier.

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

  • HTML 4: 11.2, Éléments de construction de tables
  • HTML 4: Annexe B, Section 5.1.2: Affichage incrémentiel
  • HTML 5: Algorithme de traitement des lignes
  • CSS2: 17.5.2 Algorithmes de largeur de table, la propriété ‘table-layout’
  • Projet de documentation sur les normes de conception Web américaines | les tables