web-dev-qa-db-fra.com

"Ce site semble utiliser un effet de positionnement lié au défilement. Cela pourrait ne pas fonctionner correctement avec le panoramique asynchrone"

On m'a donné cet avertissement inhabituel de Firefox. L'effet de positionnement auquel il fait référence est un div que je fais pivoter en tant que facteur de la hauteur de défilement. Je n'ai jamais eu de problèmes avec cela, mais est-ce quelque chose qui devrait me préoccuper? Est-il possible d'avoir de tels effets sans cet avertissement? Le code JavaScript illustrant ce problème est:

//Rotate gears in about section
    $('.gear').css({
        'transition': 'transform 1s ease-out',
        '-webkit-transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
        '-moz-transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
        '-ms-transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
        'transform': 'rotate(' + Math.round(wScroll / 2) + 'deg)',
    });
  • wScroll est la hauteur de défilement actuelle
26
Michael Hancock

Je pense que l'avertissement continue:

... voir https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects pour plus de détails et pour participer à la discussion sur les outils et fonctionnalités associés!

Mais au cas où cette page ne serait pas claire, voici l'essentiel.

L'idée de "panoramique asynchrone" est la suivante: lorsque la page est défilée, le navigateur appelle votre gestionnaire scroll, mais il de manière asynchrone peint la page au nouveau point de défilement. . Ceci est fait pour que le défilement apparaisse réactif (@ 60 FPS) même lorsque le thread principal est occupé pendant plus de 16 ms.

Cela signifie qu'il n'est pas garanti que les effets implémentés par votre gestionnaire soient synchronisés avec la position de défilement actuelle. C'est à dire. le défilement est lisse, mais vos divs tournent avec un plus petit FPS - apparaissant janky, non lisse.  Update , vous n’avez pas saisi l’effet transition dans votre exemple - la rotation elle-même sera également fluide, mais elle pourrait commencer plus tard que la page. commence à défiler.

Je ne pense pas que vous puissiez mettre en œuvre l'effet exact que vous avez avec les technologies actuellement disponibles sans avoir ce problème.

exemple

(Notez que pour voir le APZ en action, vous devez exécuter la version de Firefox avec cette option activée. Cela nécessite notamment que Firefox s'exécute dans un processus multiple. Le mode ("e10s"), qui n’est toujours pas dans la version créée à ce jour.)

window.onscroll = function() {
  var wScroll = document.documentElement.scrollTop;
  document.getElementById("gear-css").style.transform = 'rotate(' + Math.round(wScroll / 2) + 'deg)';
  document.getElementById("gear-js") .style.transform = 'rotate(' + Math.round(wScroll / 2) + 'deg)';
  document.getElementById("gear-js").textContent = leftPad(wScroll+'', '0', 4);

  setTimeout(slowdown(500), 0);
};

function leftPad(s, ch, maxLen) { return ch.repeat(maxLen - s.length) + s; }
function slowdown(timeMs) {
  return function() {
    var start = Date.now();
    var j = "";
    for (var i = 0; (Date.now() - start < timeMs); i++)
      j = j+(start+"")*i;
  }
}


window.onload = function() {
  for (let i = 0; i < 15; i++) {
    var p = document.createElement("p");
    p.innerText = `Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
          tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
          quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
          consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
          cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
          proident, sunt in culpa qui officia deserunt mollit anim id est laborum.`;
    document.documentElement.appendChild(p);
  }
}
#gear-css, #gear-js {
  border: solid black 1px;
}
#gear-css {
  transition: transform 1s ease-out
}
<div style="position: fixed; top: 0; right: 0; padding: 3em;">
  <div id="gear-css">ooo</div>
  <div id="gear-js">ooo</div>
</div>
18
Nickolay

Je sais que cette question a été posée il y a quelque temps, cependant, le problème de performances existe toujours. Vous trouverez ci-dessous une solution alternative qui ne repose pas sur un écouteur d'événement à défilement. Cela minimise les effets de jank et de lag causés par le fil de défilement distinct qui est commun aux navigateurs Web, mettant à jour le fichier css à intervalles réguliers plutôt que lorsque la fenêtre est défilée. Cela signifie que l'avertissement de la console de développement ne s'affichera pas. Personnellement, je ne m'inquiéterais pas trop de l'avertissement ou de l'utilisation d'événements de défilement pour de petites choses telles que passer à la vitesse supérieure ou changer une classe CSS, mais si l'expérience utilisateur s'appuie directement sur l'effet, cela détruira la convivialité de la page.

var gear;
var lastPosition;
var refreshRate = 60; // fps; reduce for less overhead
var animation = "rotate(*deg)"; // css style to apply [Wildcard is *]
var link = 0.5; //what to multiply the scrollTop by

function replace(){
    if(lastPosition != document.body.scrollTop){ // Prevents unnecessary recursion
        lastPosition = document.body.scrollTop; // updates the last position to current
        gear.style.transform = animation.replace("*", Math.round(lastPosition * link)); // applies new style to the gear
    }
}

function setup(){
    lastPosition = document.body.scrollTop;
    gear = document.querySelector(".gear");
    setInterval(replace, 1000 / refreshRate); // 1000 / 60 = 16.666... Invokes function "replace" to update for each frame
}
window.addEventListener("DOMContentLoaded", setup);

Un exemple de travail peut être utilisé sur mon GitHub . Je l'ai testé sur Firefox, Chrome et Edge (fonctionne).

D'autres solutions pour éviter l'avertissement sont d'utiliser éléments collants css ou utilisez l'élément element.classList.add () et méthodes element.classList.remove () limitées à un événement window window.onscroll .

Remarque: Faites attention lorsque vous utilisez des transitions css lorsque la longueur de la transition est supérieure à l'intervalle auquel le style CSS sera mis à jour par le script (tel que comme avec le défilement des modifications basées sur les événements). Les navigateurs Webkit et EdgeHTML se comporteront de manière inattendue, conservant généralement leur position initiale jusqu'à ce que l'élément cesse d'être mis à jour par le script. À moins que ce ne soit l'effet que vous vouliez, dans ce cas, cela ne fonctionne pas de la même manière dans Firefox.

Servo Webrender, une fois intégré à Firefox, résoudra ces problèmes dans une certaine mesure (ou au moins améliorera considérablement les performances). Bien qu'il y ait toujours d'autres navigateurs avec lesquels maintenir la compatibilité.

3
QWERTYUIOPYOZO

la meilleure solution est un commutateur et une minuterie. J'expose ici la réponse pour résoudre la même erreur lorsque vous utilisez "on scroll", je vous suggère d'adapter mon script à vos besoins! https://stackoverflow.com/a/57641938/578132

0
Constantin