Perché stai sprecando soldi con Raf e come smettere di rincorrere miraggi tecnici

Perché stai sprecando soldi con Raf e come smettere di rincorrere miraggi tecnici

Ho visto decine di sviluppatori e responsabili tecnici buttare via settimane di lavoro perché convinti che Raf fosse una sorta di bacchetta magica per la fluidità delle animazioni web. Immagina la scena: un team lancia una nuova interfaccia, convinto che tutto scorra a sessanta frame al secondo, solo per scoprire che sui dispositivi mobile di fascia media degli utenti reali l'esperienza è un disastro di scatti e ritardi. Hanno seguito i tutorial base, hanno inserito le chiamate ricorsive correttamente, eppure il browser sembra soffocare. Il costo? Giornate di debugging frenetico, utenti che abbandonano il sito e un'immagine di brand che ne esce a pezzi. Il problema non è lo strumento, ma il fatto che quasi nessuno capisce cosa succeda davvero sotto il cofano quando il browser decide di ridisegnare i pixel sullo schermo.

L'illusione della sincronia perfetta con Raf

Il primo grande abbaglio è credere che richiamare questa funzione garantisca che il codice venga eseguito esattamente prima del prossimo rinfresco dello schermo senza eccezioni. Nella realtà, il browser è un arbitro spietato e sovraccarico. Se il thread principale è occupato da un calcolo pesante o da un parsing JSON infinito, il tuo tentativo di aggiornare l'interfaccia verrà ignorato o posticipato, creando quei fastidiosi salti visivi che chiamiamo "jank".

Ho lavorato su un progetto di dashboard finanziaria dove i grafici dovevano aggiornarsi in tempo reale. Il team usava questo metodo per ogni singola variazione di prezzo. Risultato: la CPU dei laptop dei clienti arrivava al 100% in pochi secondi. Non stavano ottimizzando, stavano intasando il sistema. La soluzione non è invocare l'aggiornamento più spesso, ma capire che il monitor ha una frequenza fissa (solitamente 60Hz, ma sempre più spesso 90Hz o 120Hz) e che ogni millisecondo che passi a calcolare logica dentro la funzione di callback è un millisecondo sottratto al browser per fare il suo lavoro di pittura. Se sfori il budget di circa 16 millisecondi, hai perso.

Gestire il carico di lavoro all'interno di Raf

Un errore che vedo ripetere costantemente è inserire logica di business pesante o manipolazioni DOM complesse dentro il ciclo di animazione. Molti pensano che siccome siamo dentro il momento "giusto" del frame, allora tutto sia permesso. Non è così.

Il pericolo del layout thrashing

Se dentro la callback leggi una proprietà come offsetWidth e subito dopo cambi uno stile che influenza il layout, come la larghezza, e poi leggi di nuovo un'altra proprietà, costringi il browser a ricalcolare tutto nel bel mezzo dell'esecuzione. Questo è il modo più veloce per distruggere le prestazioni. In un caso reale, ho visto un'animazione di uno slide-out menu che impiegava 300ms solo per calcolare le posizioni degli elementi interni a ogni frame. È follia pura. La regola d'oro è: leggi tutto quello che ti serve all'inizio, fuori dal ciclo se possibile, e usa la callback solo per scrivere i cambiamenti finali.

Micro-ottimizzazioni che non servono a nulla

Smetti di preoccuparti se sia meglio usare una funzione freccia o una funzione classica. Quello che conta è la quantità di oggetti che crei. Se la tua funzione di aggiornamento alloca nuovi oggetti o array a ogni iterazione, attiverai il Garbage Collector del browser così spesso che vedrai micro-pause costanti. Ho visto progetti dove la memoria saliva costantemente fino a bloccare il browser dopo cinque minuti di utilizzo solo per colpa di una gestione scellerata delle variabili temporanee dentro il loop.

Il confronto tra l'approccio amatoriale e quello professionale

Per capire davvero la differenza, guardiamo come viene gestito lo scorrimento di una pagina per attivare un'animazione di parallasse.

L'approccio sbagliato, quello che insegna il 90% dei tutorial scadenti, consiste nell'agganciare un ascoltatore all'evento di scroll che chiama direttamente le modifiche CSS. Quando l'utente scorre velocemente, l'evento viene lanciato decine di volte in pochi millisecondi, saturando la coda dei compiti del browser. L'utente percepisce una resistenza fisica, come se la pagina fosse "pesante". Il codice prova a muovere gli elementi troppo spesso, mandando in tilt il calcolo del layout.

💡 Potrebbe interessarti: honor 400 lite quando è uscito

L'approccio corretto, quello che salva le prestazioni, prevede l'uso di una variabile di stato e di un flag. Quando avviene lo scroll, si aggiorna solo il valore della posizione e si richiede un aggiornamento al sistema solo se non ce n'è già uno in coda. La logica di trasformazione degli elementi avviene solo quando il browser è effettivamente pronto a disegnare il frame successivo. In questo modo, non importa quante volte scatti l'evento di scroll: il lavoro di calcolo e di disegno avverrà esattamente una volta per frame. La fluidità che si ottiene non è un caso, ma il risultato di non aver chiesto al computer di fare un lavoro inutile.

Sottovalutare la durata e il tempo trascorso

Un errore tecnico che costa mesi di bug report è l'utilizzo di incrementi fissi per le animazioni. Scrivere qualcosa come posizione += 5 dentro la callback è un suicidio professionale. Perché? Perché non hai il controllo sulla frequenza di aggiornamento del monitor dell'utente. Se io ho uno schermo a 144Hz, la tua animazione andrà più di due volte più veloce rispetto a chi ha uno schermo a 60Hz.

Ho visto intere interfacce di gioco web diventare inutilizzabili su Macbook Pro recenti perché gli sviluppatori avevano testato solo su vecchi monitor da ufficio. La soluzione è usare il timestamp che il browser passa automaticamente alla funzione. Devi calcolare quanto tempo è passato dall'ultimo frame e moltiplicare i tuoi spostamenti per quel delta. È matematica elementare, ma la pigrizia di saltare questo passaggio porta a software che si comporta in modo imprevedibile. Se vuoi che un elemento si muova di 100 pixel in un secondo, deve muoversi di 0.1 pixel per ogni millisecondo trascorso, punto.

Dimenticare la pulizia e il risparmio energetico

Molti sviluppatori avviano un ciclo di Raf e si dimenticano di fermarlo. Questo significa che anche se l'animazione è finita, o se l'elemento non è più visibile, il browser continua a riservare risorse e a eseguire codice nel vuoto. Su un dispositivo mobile, questo drena la batteria dell'utente in modo visibile.

🔗 Leggi di più: i can't stand it traduzione

In un'applicazione di e-commerce su cui ho fatto consulenza, c'era un piccolo spinner di caricamento in un angolo che non veniva mai rimosso correttamente dal loop, anche se nascosto via CSS. Gli utenti si lamentavano che il sito faceva surriscaldare i telefoni. Non appena abbiamo introdotto un controllo per interrompere la richiesta di nuovi frame quando l'animazione non era necessaria, il consumo di energia è crollato del 40%. Bisogna sempre memorizzare l'ID restituito dalla chiamata e usarlo per cancellare l'operazione non appena il compito è terminato. Non lasciare processi appesi è il segno distintivo di chi sa cosa sta facendo.

La realtà del supporto hardware e dei driver

Un fattore che spesso viene ignorato è che stiamo lavorando sopra uno stack tecnologico profondo. Il browser parla con il sistema operativo, che parla con i driver della scheda video. Ho visto situazioni in cui Raf si comportava in modo erratico solo su certe versioni di Chrome su Windows a causa di conflitti con l'accelerazione hardware.

Non puoi dare per scontato che il comportamento sia identico ovunque. Esistono casi limite in cui il browser decide di abbassare drasticamente la frequenza di aggiornamento se rileva che la scheda video è sotto stress o se la finestra è parzialmente coperta. Se la tua logica di applicazione dipende strettamente dalla regolarità di questi battiti, il tuo sistema fallirà. La strategia migliore è disaccoppiare la logica di stato del programma dalla logica di visualizzazione. Lo stato deve avanzare in base a timer affidabili o eventi logici, mentre la visualizzazione deve limitarsi a riflettere lo stato attuale nel miglior modo possibile quando il sistema glielo permette.

Il controllo della realtà su cosa serve davvero

Se pensi che basti copiare e incollare qualche riga di codice per avere un'applicazione fluida, sei fuori strada. Ottimizzare le prestazioni web richiede una comprensione profonda di come il browser costruisce l'albero dei livelli, di come funziona il compositore della GPU e di come gestire la memoria. La verità cruda è che la maggior parte delle volte non dovresti nemmeno usare il codice manuale per le animazioni. I CSS Transitions e le Web Animations API sono spesso gestiti su un thread separato dal browser, il che significa che rimangono fluidi anche se il tuo codice JavaScript sta facendo fatica.

Usare lo strumento di cui abbiamo parlato oggi è necessario solo quando hai bisogno di un controllo totale, frame per frame, su logiche complesse che i CSS non possono gestire. Ma questo controllo comporta la responsabilità di gestire ogni singolo millisecondo con una precisione chirurgica. Se non sei disposto a misurare costantemente con il profiler del browser, a testare su dispositivi vecchi di cinque anni e a studiare la pipeline di rendering, allora produrrai solo codice mediocre che rallenta il web. Non ci sono scorciatoie: la fluidità è un lusso che si paga con l'ingegneria rigorosa, non con la speranza che il browser risolva i tuoi errori di logica.

VM

Valentina Moretti

Tra analisi e reportage, Valentina Moretti racconta i fatti con precisione, contesto e un linguaggio vicino alle persone.