Riduzione della scroll jank durante l’uso di overflow-y: scroll;

Ho un layout a 2 colonne, la colonna a destra è un elenco di risultati scorrevoli con un massimo di 200 risultati degli elementi (fondamentalmente solo un ul con overflow-y: scroll; set)

Quello che sto trovando è che la colonna di destra sta causando un po ‘di jank (che è particolarmente evidente sull’hardware di fascia bassa) quando si scorre.

Nella timeline chrome posso vedere alcuni importanti “Update Layer tree” mentre faccio scorrere la colonna. C’è un modo per capire perché “Update Layer tree” è così lungo e quali sono le proprietà CSS che influenzano maggiormente la velocità? Quando faccio clic su di esso – mi dà solo informazioni su quanto tempo ha funzionato e nient’altro.

Ho alcuni CSS in ognuno dei li che non si comportano molto bene (filtri, trasformazioni, ombre di scatole ecc.) – Se rimuovo ogni file SASS uno per uno, migliora le prestazioni di scorrimento (e alla fine rimuove jank una volta sola rimuovo tutti i CSS), ma ovviamente è difficile stabilire quale proprietà di css non si sta comportando in questo modo.

Mi chiedo se mi manca qualcosa nella timeline di Chrome che può essere utile in questo senso?

Ho provato a utilizzare la proprietà CSS di will-change per promuovere lo scorrimento su un livello diverso / forzare l’accelerazione hardware, ma ciò non fa molta differenza.

Inoltre non ci sono eventi javascript in esecuzione mentre scorrono.

Limitare a meno di 200 articoli non è un’opzione.

Ho impostato un esempio di questo (so che è un elenco più lungo di elementi, ma questo è solo per scopi dimostrativi): https://github.com/jooj123/jank/blob/master/scroll.html

Ciò che è veramente interessante è che se rimuovo l’ overflow-y: scroll; (in .map-search__results nell’esempio sopra) lo scrolling diventa molto fluido e jank scompare – perché questo ha così tanto effetto?

Ecco la timeline di Chrome (con fondamentalmente solo lunghe sezioni “Aggiorna layer tree”): inserisci la descrizione dell'immagine qui

Difficoltà:

La risposta di Paolo sul will-change: transform di will-change: transform è azzeccata , in particolare questo aiuto ha aiutato:

“Aggiungi cambierà: trasforma; Una volta aggiunto, il rect” su scroll “è sparito.”

Ma fai attenzione perché non si applica sempre in base al tuo codice base, controlla l’indicatore dei problemi di scorrimento per assicurarti che “ridisegna su scroll” sia distriggersto, per me ho dovuto disabilitare anche una proprietà -webkit-clip-path (nel mio codice effettivo – non nella demo fornita) impostato in una delle divs bambino, vedi:

inserisci la descrizione dell'immagine qui

Ho provato la tua pagina di test e ho dato un’occhiata.

Innanzitutto, con i problemi di scorrimento perf mi piace sfogliare alcune delle caselle di controllo nel riquadro di rendering:

inserisci la descrizione dell'immagine qui

Immediatamente possiamo vedere questo div chiamato “repate su scroll”. Puoi quindi verificarlo nel pannello Livelli sperimentali:

inserisci la descrizione dell'immagine qui

(Ho fatto clic con il tasto destro sull’albero e selezionato “Mostra livelli interni” btw)

Ora i costi di “albero di livello di aggiornamento” di grandi dimensioni sono generalmente causati da LOTTI di livelli o da pochi livelli di dimensioni molto grandi. In questo caso non abbiamo davvero né l’uno né l’altro. Ma abbiamo uno strato di scorrimento che non sta ottenendo lo scorrimento composito.

Scorrimento composito == scorrimento veloce == solitamente il valore predefinito. Ma in casi come questo torniamo a “main thread scrolling” che è veramente lento e sucky. Tra l’altro , crbug.com/381840 sta per essere riparato e dovrebbe risolvere automaticamente questo caso di test. Sìì! Ma possiamo aggirarlo per ora.

La soluzione

Hai accennato al fatto che hai provato will-change e che non ha avuto alcun effetto, ma provarlo da solo ha funzionato alla grande. Appartiene all’elemento con overflow impostato, in questo caso è il selettore .map-search__results . Aggiungi will-change: transform; . Una volta aggiunto, il rect “repate su scroll” è sparito. E misurando con la timeline in seguito ed è MOLTO meglio.

Ecco una vista prima / dopo:

inserisci la descrizione dell'immagine qui link al visualizzatore

In bocca al lupo!

Se il tuo problema è notevolmente visibile durante lo scorrimento dovresti essere in grado, con le tabs Timeline e Stili aperte negli strumenti di sviluppo, deselezionare gli stili che si applicano agli elementi uno alla volta nella scheda degli stili e vedere come influenza lo scorrimento . In questo modo puoi testare ogni regola di stile in modo indipendente invece che interi file CSS. E se utilizzi la funzione sourcemaps nel tuo CSS, dovresti riuscire facilmente a trovare la regola incriminata nei tuoi file CSS effettivi e apportare modifiche.

Se non hai familiarità con l’utilizzo della scheda degli stili: con gli strumenti di sviluppo di Chrome aperti, utilizza lo strumento Impostazioni (angolo in alto a sinistra del riquadro degli sviluppatori) per selezionare gli elementi che ritieni possano darti problemi. Tutti gli stili associati o sovrascritti per l’elemento selezionato verranno elencati nella scheda degli stili. È quindi ansible distriggersrli uno alla volta. Puoi usare l’ispettore per approfondire quanto vuoi attraverso gli oggetti annidati.

AGGIORNARE:

Ho tirato giù il codice dopo la modifica e l’ho guardato molto attentamente. Ho notato che l’overflow che hai avuto era sul tuo ul elemento. Personalmente non ho mai usato un overflow su un ul (di solito preferisco un contenitore come div per quello), quindi per curiosità ho rimosso l’ overflow-y:scroll dal tuo ul e mettilo sul contenuto .right-content div .right-content (e imposta è altezza al 100%) e lo scrolling janky è sparito.

Per quanto riguarda il perché, posso solo speculare, ma credo che abbia a che fare con il numero di elementi che stai scorrendo. Quando il tuo overflow è sull’UL, stai scorrendo direttamente TUTTI questi elementi li . Quando è sul div contenente, in realtà stai scorrendo SOLO l’ ul , quindi credo che questo processo abbia molta meno matematica da determinare quando si calcola il posizionamento degli oggetti in movimento. 1 posizionamento div per regolare contro centinaia di li per regolare.

confronto di vernice

Se confronti le linee temporali nelle immagini sopra vedrai la differenza. Quello in cima è la versione originale con overlflow-y:scroll su ul . È ansible passare con il mouse su tutte quelle piccole righe nel processo di aggiornamento dell’albero e vedere che ci sono centinaia di oggetti dipinti. Questi sono i tuoi oggetti li . Nella seconda timeline è la versione in cui ho rimosso l’overflow da ul e l’ho applicato al div contenente. Puoi vedere in questa timeline che il processo dell’albero di aggiornamento ha solo un elemento da dipingere quale è l’ ul . Se guardi le dimensioni degli articoli vedrai anche la differenza di dimensioni.