2016-05-08 4 views
15

Ho ricevuto questo avviso insolito da Firefox. L'effetto di posizionamento a cui fa riferimento è un div I ruota come un fattore dell'altezza di scorrimento. Non ho mai avuto problemi con questo, ma è qualcosa di cui dovrei preoccuparmi? Esiste comunque un tale effetto senza questo avvertimento? Il JavaScript che illustra questo problema è:"Questo sito sembra utilizzare un effetto di posizionamento a scorrimento, che potrebbe non funzionare correttamente con la panoramica asincrona"

//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 è l'attuale altezza di scorrimento

risposta

12

L'avvertimento, credo, continua a dire:

... vedi https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects per ulteriori dettagli e per partecipare alla discussione sugli strumenti e le funzionalità correlate!

Ma nel caso in cui la pagina non è chiara, ecco il succo di esso.

L'idea di "panning asincrono" è questo: quando la pagina viene fatto scorrere, il browser chiama il gestore scroll, ma anche in modo asincrono dipinge pagina al nuovo scroll-point. Questo viene fatto per rendere lo scorrimento reattivo (@ 60 FPS) anche quando il thread principale è occupato per più di 16 ms.

Ciò significa che gli effetti che gli strumenti del gestore non sono in grado di sincronizzare con la posizione di scorrimento corrente. Cioè lo scorrimento è scorrevole, ma le tue div ruotano con un FPS più piccolo - che appare janky, non liscio.Aggiornamento, manca l'effetto transition nell'esempio: anche la rotazione stessa sarà scorrevole, ma potrebbe iniziare più tardi rispetto a quando la pagina inizia a scorrere.

Non penso che sia possibile implementare l'effetto esatto che si ha con le tecnologie attualmente disponibili senza avere questo problema.

esempio

(Si noti che per vedere il APZ in azione, è necessario essere in esecuzione la versione di Firefox con esso abilitato. In particolare, questo richiede Firefox ad essere in esecuzione in un multiprocesso ("e10s") mode, che non è ancora nel comunicato si basa in questo momento.)

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>

+0

Grazie Nickolay, come dici tu la pagina non è molto chiara ma hai sicuramente aiutato! –

+2

@MichaelHancock: nota che MDN è un wiki, quindi se hai suggerimenti su come rendere la pagina più chiara alle persone che non stanno costruendo un browser, sono i benvenuti. Ricordo che hanno avuto problemi con gli spammer, quindi creare un nuovo account potrebbe essere più difficile di quanto debba essere, ma in ogni caso se sei interessante nell'aiutare, per favore [mettiti in contatto] (https://developer.mozilla.org/it-iT/docs/MDN/Comunità/Conversazioni)! – Nickolay

1

so che questa domanda è stato chiesto qualche tempo fa, tuttavia, il problema di prestazioni esiste ancora. Di seguito è una soluzione alternativa che non si basa su un listener di eventi di scorrimento. Ciò minimizza jank e lag causati dal thread di scorrimento separato comune tra i browser Web, aggiornando il css a intervalli regolari piuttosto che quando si scorre la finestra. Ciò significa che l'avviso della console di sviluppo non verrà visualizzato. Personalmente non sarei troppo preoccupato per l'avviso o per gli eventi di scorrimento per piccole cose come girare una marcia o cambiare una classe di css, tuttavia, se l'esperienza dell'utente dipende direttamente dall'effetto, distruggerà la fruibilità della pagina.

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 esempio di lavoro può essere utilizzato on my GitHub. L'ho provato su Firefox, Chrome e Edge (funziona).

Altre alternative evitando l'avvertimento devono utilizzare css sticky elements o utilizzare il element.classList.add() e element.classList.remove() metodi limnked ad un window.onscroll evento.

Nota: Prestare attenzione all'utilizzo delle transizioni css in cui la lunghezza della transizione è più lunga dell'intervallo in cui lo stile CSS verrà aggiornato dallo script (ad esempio con le modifiche basate su eventi di scorrimento). I browser basati su Webkit e EdgeHTML si comportano in modi inaspettati a questo, di solito rimangono nella loro posizione iniziale fino a quando l'elemento smette di essere aggiornato dallo script. A meno che questo non sia l'effetto che intendevi, nel qual caso non funziona allo stesso modo in Firefox.

Servo Webrender, se integrato in Firefox risolverà questi problemi in una certa misura (o almeno migliorerà le prestazioni in modo considerevole). Anche se ci saranno ancora altri browser per mantenere la compatibilità con.

Problemi correlati