Connecting...

Cancel

La storia di Gyroscope

10 principi per animazioni web fluide

La guida completa alle animazioni fluide a 60fps sul tuo sito

10 principi per animazioni web fluide

La guida completa alle animazioni a 60fps con i CSS

Da quando abbiamo lanciato Gyroscope l’anno scorso, in tanti ci hanno chiesto della libreria JavaScript che usiamo per le nostre animazioni. Abbiamo pensato di rilasciarla al pubblico, ma in realtà non è lì che avviene la magia.

Non vogliamo che le persone si sentano dipendenti da un plugin JavaScript speciale che risolve questi problemi per incanto. Nella maggior parte dei casi ci limitiamo a sfruttare i miglioramenti recenti nelle prestazioni dei browser, nelle GPU e nelle specifiche CSS3.

Non esiste una bacchetta magica per fare grandi animazioni, se non passare un sacco di tempo a testarle e a ottimizzarle. Però, dopo anni di esperimenti e di limiti prestazionali sbattuti in faccia dai browser, siamo arrivati a una serie di principi di design & di codice che sembrano portare in modo affidabile ad animazioni piacevoli. Queste tecniche dovrebbero darti pagine fluide, che funzionano nei browser moderni su desktop e mobile e, soprattutto, sono facili da mantenere.

La tecnologia e l’implementazione saranno un po’ diverse per ciascuno, ma i principi generali dovrebbero essere utili in quasi ogni situazione.

Che cos’è un’animazione?

Le animazioni esistono da prima di internet, e farle bene è una cosa a cui potresti dedicare una vita intera. Farle per il web, però, porta con sé vincoli e sfide particolari.

Per avere una fluidità a 60fps, ogni fotogramma deve essere disegnato in meno di 16 ms! Non è tantissimo tempo, quindi dobbiamo trovare modi molto efficienti di disegnare ogni fotogramma per restare fluidi.

Ci sono decine di modi di fare animazioni sul web. Per esempio la pellicola, un approccio che esiste da prima di internet: fotogrammi disegnati a mano leggermente diversi tra loro che si sostituiscono molte volte al secondo per creare l’illusione del movimento.

Twitter ha usato di recente questo approccio semplice per la sua nuova animazione del cuore, scorrendo uno sprite di fotogrammi.

Questo effetto si poteva fare con una montagna di elementi minuscoli animati uno per uno, o magari con un SVG, ma sarebbe stato inutilmente complesso e probabilmente meno fluido.

In molti casi vorrai usare la proprietà CSS transition per animare in automatico un elemento mentre cambia. Questa tecnica è nota anche come “tweening”, cioè la transizione tra due valori diversi. Ha il vantaggio di essere facilmente annullabile o reversibile senza dover costruire tutta quella logica. È l’ideale per le animazioni “imposta e dimentica”, come le sequenze di apertura, o per interazioni semplici come gli hover.

Per approfondire: All you need to know about CSS Transitions

In altri casi la proprietà CSS animation, basata sui keyframe, può essere l’ideale per dettagli di sfondo che girano di continuo. Per esempio gli anelli del logo Gyroscope sono programmati per ruotare senza sosta. Un altro tipo di cosa che si presta bene alla sintassi CSS animation sono i rapporti tra ingranaggi.

Detto questo, ecco alcuni consigli che si spera miglioreranno parecchio le prestazioni delle tue animazioni…

#1

Non cambiare nessuna proprietà a parte opacity o transform!

Anche se pensi che possa andare bene, non farlo!

Da solo, questo principio di base ti porta all’80% della strada, anche su mobile. Probabilmente l’hai già sentito: non è un’idea originale, ma viene seguita di rado. È l’equivalente web di “mangia sano e fai attività fisica”: suona come un buon consiglio, ma di solito lo ignori.

È abbastanza semplice una volta che ti abitui a ragionare così, ma può essere un salto grosso per chi è abituato ad animare le proprietà CSS tradizionali.

Per esempio, se vuoi rimpicciolire qualcosa, puoi usare transform: scale() invece di cambiare la larghezza. Se vuoi spostarlo, invece di mettere mano a margini o padding, che costringerebbero a ricostruire tutto il layout della pagina a ogni fotogramma, ti basta un semplice transform: translateX o transform: translateY.

Perché funziona?

Per un essere umano, cambiare larghezza, margini o altre proprietà può non sembrare granché, o addirittura sembrare preferibile perché è più semplice, ma in termini di quello che deve fare il computer sono mondi lontanissimi e uno dei due è molto, molto peggio.

I team dei browser hanno fatto un gran lavoro per ottimizzare queste operazioni. Le trasformazioni sono davvero facili da eseguire in modo efficiente e spesso riescono a sfruttare la scheda grafica senza ridisegnare gli elementi.

Al primo caricamento della pagina puoi dare di matto: arrotonda tutti gli angoli, usa immagini, metti ombre ovunque, e se ti senti particolarmente spericolato puoi perfino fare una sfocatura dinamica. Se succede una volta sola, qualche millisecondo di calcolo in più non fa differenza. Ma una volta che il contenuto è disegnato, non vuoi continuare a ricalcolare tutto.

Per approfondire: Moving elements with translate (Paul Irish)

#2

Nascondi il contenuto in bella vista.

Usa pointer-events: none insieme all’opacità a zero per nascondere gli elementi

Su questo ci possono essere delle avvertenze da browser a browser, ma se stai costruendo solo per webkit e per gli altri browser moderni ti semplificherà molto la vita.

Tanto tempo fa, quando le animazioni si gestivano con animate() di jQuery, gran parte della complessità nel far comparire e sparire le cose stava nel passare da display: none a block al momento giusto. Troppo presto e l’animazione non finiva, troppo tardi e ti ritrovavi contenuti invisibili a opacità zero che coprivano la pagina. Serviva una callback per ogni cosa per fare pulizia a fine animazione.

La proprietà CSS pointer-events (che c’è ormai da parecchio tempo, ma si usa poco) fa in modo che le cose non rispondano ai clic o alle interazioni, come se non ci fossero. Si può attivare e disattivare facilmente via CSS senza interrompere le animazioni e senza influire in alcun modo sul rendering o sulla visibilità.

Unita a un’opacità pari a zero, ha praticamente lo stesso effetto di display none, ma senza il costo prestazionale di innescare nuovi rendering. Quando nascondo qualcosa, di solito mi basta mettere l’opacità a 0 e disattivare i pointer-events, e poi posso dimenticarmi dell’elemento sapendo che si arrangia da solo.

Funziona particolarmente bene con gli elementi in posizione assoluta, perché puoi stare tranquillo che non hanno assolutamente alcun impatto sul resto della pagina.

Ti dà anche un po’ più di margine, perché i tempi non devono essere perfetti: non è la fine del mondo se un elemento resta cliccabile o copre altre cose per un secondo in più di quanto sia rimasto visibile, o se diventa cliccabile solo a dissolvenza completata.

#3

Non animare tutto nello stesso momento.

Usa piuttosto la coreografia.

Una singola animazione può essere fluida da sola, ma insieme a tante altre probabilmente si rovinerà. È facilissimo fare una demo di base in cui quasi tutto gira liscio, ed è un ordine di grandezza più difficile mantenere quelle prestazioni su un sito intero. Per questo è importante programmarle bene.

Vuoi distribuire i tempi in modo che non parta e non si muova tutto esattamente nello stesso istante. Di solito 2 o 3 cose possono muoversi insieme senza rallentare, soprattutto se sono partite in momenti leggermente diversi. Oltre a quello rischi picchi di lag.

A meno che sulle tue pagine ci sia letteralmente una cosa sola, è importante capire il concetto di coreografia. Sembra un termine da danza, ma è altrettanto importante per animare le interfacce. Le cose devono entrare dalla direzione giusta e al momento giusto. Anche se sono tutte separate, devono sembrare parte di un unico insieme ben progettato.

Il material design di Google ha qualche spunto interessante sull’argomento. Non è l’unico modo giusto di fare le cose, ma è qualcosa a cui dovresti pensare e che dovresti provare.

Per approfondire: Google Material Design · Motion

#4

Aumentare leggermente i ritardi delle transizioni rende facile coreografare il movimento.

Coreografare le animazioni è davvero importante e richiederà molta sperimentazione e molti test prima di sentirle giuste. Il codice per farlo, però, non deve essere per forza complicato.

Di solito cambio una sola classe su un elemento genitore (spesso sul body) per innescare un mucchio di transizioni, e ognuna ha il suo transition-delay diverso per entrare al momento giusto. Dal punto di vista del codice devi preoccuparti di un solo cambio di stato, senza dover mantenere decine di tempi nel tuo JavaScript.

Le animazioni nell’estensione Chrome di Gyroscope

Scaglionare una serie di elementi è un modo facile e semplice di coreografarli. È potente perché allo stesso tempo è bello da vedere e ti fa guadagnare prestazioni preziose: ricordati che vuoi avere solo poche cose in movimento nello stesso istante. Vorrai distanziarli abbastanza perché ognuno risulti fluido, ma non così tanto da far sembrare tutto troppo lento. Devono sovrapporsi quanto basta perché sembri un flusso continuo e non una catena di cose separate.

Esempio di codice

Ci sono un paio di tecniche semplici per scaglionare gli elementi, soprattutto quando si tratta di un lungo elenco di cose. Se gli elementi sono meno di 10, o sono in numero molto prevedibile (come in una pagina statica), di solito indico i valori nel CSS. È la soluzione più semplice e più facile da mantenere.

Un semplice ciclo in SASS

Per elenchi più lunghi o contenuti molto dinamici, i tempi si possono impostare in modo dinamico ciclando su ogni elemento.

Un semplice ciclo in javascript

Di solito ci sono due variabili: il ritardo di partenza e poi il ritardo tra un elemento e l’altro. È un equilibrio difficile da trovare, ma quando becchi la combinazione giusta di numeri sarà semplicemente perfetto.

#5

Usa un moltiplicatore globale per progettare al rallentatore

E poi accelera tutto in un secondo momento.

Nel design delle animazioni il tempo è tutto. Il 20% del lavoro è implementare qualcosa, l’altro 80% è trovare i parametri & le durate giuste perché tutto sia sincronizzato e fluido.

Soprattutto quando lavori sulla coreografia di più elementi e cerchi di spremere prestazioni e concorrenza dalla pagina, vedere tutto al rallentatore ti renderà la vita molto più facile.

Che tu stia usando Javascript o un preprocessore CSS come SASS (che adoriamo), dovrebbe essere abbastanza semplice fare due conti in più e costruire tutto usando delle variabili.

Fai in modo che sia comodo provare velocità o tempi diversi. Per esempio, se un’animazione scatta anche a 1/10 della velocità, forse c’è qualcosa di sbagliato alla radice. Se invece scorre liscia allungata 50 volte, è solo questione di trovare la velocità massima a cui riesce a girare. A velocità piena può essere difficile notare problemi da 5 millisecondi, ma se rallenti tutto diventano evidentissimi.

Soprattutto per le animazioni molto complesse, o per risolvere colli di bottiglia prestazionali difficili, poter vedere le cose al rallentatore può essere davvero utile.

L’idea di fondo è che vuoi infilare tanti dettagli perfetti mentre va piano, e poi accelerare tutto quanto perché risulti perfetto. Sarà una differenza sottilissima, ma l’utente noterà la fluidità e i dettagli.

Questa funzione fa parte di OS X: se fai shift-clic sul pulsante di riduzione a icona o sull’icona di un’app, la vedi animarsi al rallentatore. A un certo punto avevamo perfino implementato questa funzione di rallentatore su Gyroscope, attivandola con la pressione di shift.

#6

Registra dei video della tua UI e riguardali per avere una preziosa prospettiva in terza persona.

A volte un punto di vista diverso ti aiuta a vedere le cose più chiaramente, e il video è un ottimo modo per farlo.

C’è chi costruisce un video in after effects e poi prova a implementarlo su un sito. Io spesso finisco per fare il percorso opposto, e provo a ricavare un bel video dalla UI di un sito.

Riuscire a pubblicare un Vine* o un video di qualcosa è un’asticella piuttosto alta. Un giorno ero entusiasta di una cosa che avevo costruito e ho provato a registrarla per condividerla con qualche amico.

Però, riguardandola, ho notato un mucchio di cose non un granché. C’era un grosso picco di lag e tutti i tempi erano leggermente sbagliati. Mi ha fatto un po’ rabbrividire e, invece di mandarla, ho capito che c’era ancora molto lavoro da fare.

È facile sorvolare su queste cose mentre le usi in tempo reale, ma guardare le animazioni in video, più e più volte o al rallentatore, rende qualsiasi problema evidentissimo.

Dicono che la telecamera aggiunga 10 libbre. Forse aggiunge anche 10 fotogrammi.

Ormai è diventata una parte importante del mio metodo di lavoro: guardo video al rallentatore delle mie pagine e faccio modifiche se qualche fotogramma non mi convince. È facile dare la colpa ai browser lenti, ma con un po’ di ottimizzazione e di test in più è possibile risolvere tutti quei problemi.

Quando non ti vergogni più dei picchi di lag catturati in video e senti che il video è abbastanza bello da condividere, allora la pagina è probabilmente pronta per uscire.

#7

L’attività di rete può causare lag.

Dovresti precaricare o ritardare le richieste HTTP pesanti

Le immagini sono una delle grandi colpevoli, che si tratti di poche immagini grosse (magari uno sfondo grande) o di tantissime piccole (immagina 50 avatar che si caricano), o semplicemente di tanti contenuti (una pagina lunga con immagini fino al footer).

Quando la pagina si carica la prima volta, un mucchio di cose vengono inizializzate e scaricate. Avere analytics, pubblicità e altri script di terze parti peggiora ulteriormente la situazione. A volte ritardare tutte le animazioni di qualche centinaio di millisecondi dopo il caricamento fa miracoli per le prestazioni.

Non ottimizzare troppo su questo punto finché non diventa necessario, ma una pagina complicata può richiedere ritardi e tempi dei contenuti molto precisi per girare fluida. In generale vorrai caricare meno dati possibile all’inizio, e poi continuare a caricare il resto della pagina una volta finiti i lavori pesanti e le animazioni di apertura.

Nelle pagine con molti dati, il lavoro per caricare tutto può essere notevole. Un’animazione che funziona bene con contenuti statici può sfasciarsi appena inizi a caricarci sopra dati reali nello stesso momento. Se qualcosa sembra dover funzionare, o a volte è fluido e altre volte no, ti suggerisco di controllare l’attività di rete per assicurarti di non stare facendo altro nello stesso momento.

#8

Non agganciarti direttamente allo scroll.

Sembra un’idea forte, ma non lo è per niente.

Le animazioni basate sullo scroll hanno guadagnato molta popolarità negli ultimi anni, soprattutto quelle con parallasse o altri effetti speciali. Se siano un buon design o meno è discutibile, ma ci sono modi migliori e peggiori di implementarle a livello tecnico.

Un modo discretamente performante di fare cose di questa categoria è trattare il raggiungimento di una certa distanza di scroll come un evento, e far partire le cose una volta sola. A meno che tu non sappia davvero il fatto tuo, ti suggerirei di evitare questa categoria, perché è facilissimo sbagliare ed è molto difficile da mantenere.

Ancora peggio è costruirsi la propria barra di scorrimento invece di usare quella predefinita, il cosiddetto scrolljacking. Per favore non farlo.

È una di quelle regole particolarmente utili su mobile, ma è probabilmente buona pratica anche per l’esperienza utente ideale.

Se hai in mente un tipo di esperienza specifica basata sullo scroll o su eventi particolari, ti suggerirei di costruirne in fretta un prototipo per verificare che possa girare bene, prima di passare molto tempo a progettarla.

#9

Testa su mobile presto & spesso.

La maggior parte dei siti viene costruita su un computer, e testata quasi sempre sulla stessa macchina su cui è stata costruita. Così l’esperienza mobile & le prestazioni delle animazioni finiscono spesso in secondo piano. Alcune tecnologie (come canvas) o alcune tecniche di animazione possono rendere peggio su mobile.

Però, se il codice è scritto & ottimizzato bene (vedi la regola #1), l’esperienza mobile può essere perfino più fluida di quella su computer. L’ottimizzazione per il mobile una volta era un tema molto complicato, ma i nuovi iPhone ormai sono più veloci della maggior parte dei portatili! Se hai seguito i consigli precedenti, è molto probabile che ti ritrovi con ottime prestazioni su mobile senza fare altro.

L’uso da mobile sarà una parte grande e molto importante di quasi ogni sito. Può sembrare estremo, ma ti suggerirei di guardarlo solo dal telefono per una settimana intera. Essere costretti a usare la versione mobile non dovrebbe sembrare una punizione, ma spesso lo è.

Continua a fare migliorie di design & di prestazioni finché non risulta curata e comoda quanto la versione grande del sito.

Se ti obblighi a usare solo la versione mobile per una settimana, probabilmente finirai per ottimizzarla al punto da renderla un’esperienza migliore di quella grande. Ma vale la pena innervosirsi usandola tutti i giorni, se questo significa che i problemi vengono risolti prima che li incontrino i tuoi utenti!

#10

Testa spesso su più dispositivi

Dimensione dello schermo, densità o tipo di dispositivo possono avere grandi conseguenze

Ci sono molti fattori oltre a mobile contro desktop che possono cambiare radicalmente le prestazioni: se uno schermo è “retina” o no, il numero totale di pixel della finestra, quanto è vecchio l’hardware e così via.

Anche se Chrome e Safari sono entrambi browser basati su Webkit con una sintassi simile, hanno entrambi le loro stranezze. Ogni aggiornamento di Chrome può sistemare cose e introdurne di nuove rotte, quindi devi stare costantemente sul pezzo.

Ovviamente non vuoi costruire solo per il minimo comune denominatore, quindi trovare modi intelligenti per aggiungere o togliere progressivamente le rifiniture può essere davvero utile.

Passo di continuo dal mio minuscolo MacBook Air al mio enorme iMac, e ogni giro rivela piccoli problemi e piccoli miglioramenti da fare, soprattutto in termini di prestazioni delle animazioni ma anche di design generale, densità di informazioni, leggibilità e altro.

Le media query possono essere strumenti molto potenti per affrontare questi segmenti diversi: applicare stili diversi in base all’altezza o alla larghezza è l’uso tipico delle media query, ma si possono usare anche per intervenire in base alla densità di pixel o ad altre proprietà. Anche capire il sistema operativo e il tipo di dispositivo può essere utile, perché le prestazioni su mobile possono essere molto diverse da quelle su computer.

Spero che queste tecniche ti tornino utili nel tuo prossimo progetto. Buona fortuna!