web-dev-qa-db-fra.com

Chrome défilement lent avec des éléments de position fixes

Sur mon j'ai un DIV fixe en haut, 3 onglets fixes et un div fixe en bas (cela ne sera affiché que lorsque vous serez connecté - à l'avenir).

J'obtiens de mauvaises performances de défilement sur Chrome uniquement - FF & IE sont très bien.

J'ai préparé des rapports de problèmes concernant Chrome, le positionnement fixe et le défilement et je voulais voir si quelqu'un avait des suggestions? J'aimerais vraiment corriger ces éléments à leur emplacement, mais j'aimerais également de bonnes performances de défilement dans Chrome.

Des idées sur un correctif?

Remarque: son beaucoup plus perceptible lors d'un zoom sur le chrome ...

Mise à jour: j'ai lu que d'autres personnes ont des problèmes similaires et ont mis à jour ce Chrome , qui a ensuite été fusionné en 136555 , prétendument corrigé depuis Chrome 26.

41
Adam

Problème et comment le surveiller

La raison en est que Chrome pour certaines raisons, décide qu'il doit recoder et redimensionner toutes les images lorsqu'un panneau fixe les recouvre. Vous pouvez le voir particulièrement bien avec

Clic droit Inspecter Chronologie Appuyez sur ⏺ Enregistrer

► Revenez à la page et faites glisser la barre de défilement de haut en bas (le défilement de la molette de la souris n'est pas aussi efficace)

Modifier (9/1/2016): Depuis la publication de ceci, Chrome a ajouté de nouvelles fonctionnalités pour aider à surveiller cela:

Clic droit Inspecter Rendu (onglets inférieurs)

☑ Défilement des performances
☑ Peinture clignotante
☑ Compteur FPS (moins important, mais peut être utile)

Cela vous aidera à identifier exactement quels éléments nécessitent des repeints sur les parchemins et à les mettre en évidence clairement à l'écran.

Cela semble être juste un problème avec la méthode Chrome utilise pour déterminer si un élément inférieur doit être repeint.

Pour aggraver les choses, vous ne pouvez même pas contourner le problème en créant un div au-dessus d'un div défilant pour éviter d'utiliser le position:fixed attribut. Cela provoquera en fait le même effet. À peu près Chrome dit si quelque chose sur la page doit être dessiné sur une image (même dans un iframe, div ou quoi que ce soit), repeignez cette image. Donc, malgré quel div/frame vous défilent, le problème persiste.

.

La solution Easy Hack

Mais j'ai trouvé un hack pour contourner ce problème qui semble avoir peu d'inconvénients.

En ajoutant ce qui suit aux éléments fixes

/* Edit (9/1/2016): Seems translate3d works better than translatez(0) on some devices */
-webkit-transform: translate3d(0, 0, 0);

Certains navigateurs peuvent l'exiger pour éviter le scintillement

-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;

Cela place l'élément fixe dans sa propre couche de composition et force le navigateur à utiliser l'accélération GPU.

EDIT: n problème potentiel m'a été signalé par albb ; lors de l'utilisation de transform, tous les descendants position:fixed les éléments seront fixés sur cette couche de composition plutôt que sur la page entière.

.

Solution alternative

Alternativement, vous pouvez simplement masquer la navigation supérieure pendant le défilement et la ramener ensuite. Voici un exemple qui pourrait fonctionner sur l'en-tête de stackoverflow.com ou sur un site comme theverge.com s'il est collé dans DevTools> Console (ou tapez manuellement " javascript: " dans la barre d'URL de cette page et collez le code ci-dessous après et appuyez sur Entrée):

/* Inject some CSS to fix the header to the top and hide it
 * when adding a 'header.hidden' class name. */
var css= document.createElement("style");
css.type = 'text/css'; 
css.innerHTML = 'header { transition: top .20s !important; }';
css.innerHTML += 'header.hideOnScroll { top: -55px !important; }';
css.innerHTML += 'header { top: 0 !important; position: fixed !important; }';
document.head.appendChild(css);

var header = document.querySelector("header");
var reinsertId = null; /* will be null if header is not hidden */

window.onscroll = function() {
    if(!reinsertId) { 
      /* Hides header on scroll */
      header.classList.add("hideOnScroll");
      setTimeout(function() { header.style.visibility = "hidden"; }, 250);
    } else {
      /* Resets the re-insert timeout function */
      clearTimeout(reinsertId);
    }
    /* Re-insert timeout function */
    reinsertId = setTimeout(function(){
      header.classList.remove("hideOnScroll");
      header.style.visibility = "visible";
      reinsertId = null;
    }, 1500);
};
83
corylulu

La première solution de @Corylulu fonctionne, mais pas complètement (encore un peu bégaiement, mais beaucoup moins). J'ai aussi dû ajouter -webkit-backface-visibility: hidden; à l'élément fixe pour être libre de bégaiement.

Donc pour moi, ce qui suit a fonctionné comme un charme pour empêcher le défilement vers le bas dans chrome lors de l'utilisation d'éléments fixes sur la page:

-webkit-transform: translateZ(0);
-webkit-backface-visibility: hidden;

Edit: Webkit-transform et webkit-backface-visibilité provoquent tous deux des polices et des images floues. Assurez-vous donc que vous n'appliquez les deux que sur le survol.

17
Mag4work

Ajoutez cette règle à votre élément fixe,

will-change: transform;

Lisez la solution de ici ,
et lisez la propriété qui changera la propriété de ici .

5
BBeta

Il y a un rapport de bogue récent sur ce problème particulièrement ennuyeux: http://code.google.com/p/chromium/issues/detail?id=15531

Cela a à voir avec la combinaison d'éléments flottants et de grandes images. Toujours un problème sur Chrome Canary 24.0.1310.0.

2
surjikal

Il existe plusieurs façons d'accélérer ce frontal, essayez le PageSpeed ​​Insights Chrome pour quelques idées. Personnellement, je recommanderais de reconstruire ce frontal) avec le même design au-dessus d'un framework comme Twitter's Bootstrap , mais si vous souhaitez des détails sur cette interface:

  • Comme vous le dites, le positionnement de votre barre d'en-tête cause le plus de temps en termes de rendu CSS ( résultats des tests de résistance CSS ). Débarrassez-vous de cela grande image qui est là et remplacez-le par une image d'arrière-plan de 1px de large. Vous redimensionnez également des images comme votre logo (et toutes les autres images dans cet en-tête) inutilement, remplacez-les par des versions à taille réelle
  • Vous pourriez économiser beaucoup d'octets transférés par optimisation toutes vos images de contenu
1
AlecRust