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 actuelleJe 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.
(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>
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é.
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