I contenuti di questo sito sono stati tradotti mediante intelligenza artificiale (IA) o tecnologia di traduzione automatica e potrebbero contenere errori.

Skip to content

Miglioramento di 30 volte dell'utilizzo della memoria front-end durante il caricamento del carosello

Nel secondo trimestre del 2020 abbiamo effettuato una rifattorizzazione tecnica della pagina delle esperienze, riscrivendola in React e utilizzando l'API REST. Tuttavia, durante l'implementazione, abbiamo riscontrato un problema interessante.

Nella pagina delle esperienze sono presenti circa 20 caroselli, ciascuno con almeno 60 riquadri. Pertanto, la pagina visualizzerà oltre 1.200 esperienze, comprese informazioni rilevanti quali titolo, valutazione degli utenti, utenti simultanei e miniatura. In ciascun carosello, cliccando sulla freccia di scorrimento a destra verrà inviata una richiesta per caricare il batch successivo di esperienze, qualora ve ne fossero altre. I nuovi dati risultanti dalla richiesta verranno quindi aggiunti al carosello, il che significa più nodi aggiunti nel DOM e più miniature visualizzate nel browser. L'utilizzo della memoria all'interno del browser aumenterà man mano che gli utenti scorreranno per richiedere più dati, e quindi l'esperienza utente rallenterà e inizierà a presentare ritardi.

Profilo della memoria

Possiamo utilizzare gli Strumenti per sviluppatori di Chrome per analizzare questo problema. La prima istantanea viene acquisita al caricamento iniziale della pagina, mentre la seconda viene acquisita dopo che l'utente ha cliccato 12 volte sul pulsante di scorrimento successivo in un carosello. Si osserva un aumento di circa 9,7 MB nell'utilizzo della memoria dovuto a oltre 100 nodi stringa e al maggiore rendering delle miniature.

Soluzione

Quando il carosello scorre, gli utenti visualizzano solo gli elementi presenti nella finestra del carosello. Ad esempio, su un laptop con risoluzione 1920×1080, in modalità browser a schermo intero, saranno visibili solo circa 9 elementi alla volta. Pertanto, non è necessario rendere tutti i nodi e le miniature invisibili insieme né trasferire nel DOM ulteriori dati restituiti dalla richiesta.

Ecco quindi l'idea: dopo aver recuperato i dati grezzi dalla richiesta API per la prima volta, costruiamo un array della stessa lunghezza in preparazione del rendering nel DOM. All'interno dell'array di rendering, possiamo popolare solo i dati sufficienti a riempire la visualizzazione e a scorrere alla pagina successiva. Il resto dell'array verrà riempito solo quando la finestra di visualizzazione verrà fatta scorrere in prossimità di esso. Assegniamo due indici per registrare l'intervallo dei dati di rendering: renderingStartIndex e renderingEndIndex. Impostiamo un cursore per indicare quale posizione iniziale nell'elenco è visibile. Durante lo scorrimento, dobbiamo aggiornare continuamente il cursore all'indice del primo elemento visibile. Prima che l'animazione di scorrimento sia terminata, dovremo verificare se il cursore successivo si trova all'interno dell'array dei dati di rendering. In base alle dimensioni della finestra del carosello e delle schede, possiamo facilmente capire quanti elementi visibili entreranno nella finestra di visualizzazione. Quindi, dobbiamo assicurarci che gli elementi della finestra corrente e di quella successiva si trovino all'interno dell'intervallo dell'array dei dati di rendering. In caso contrario, preleviamo elementi dai dati grezzi per riempire l'elenco vuoto, cancellando al contempo i dati precedenti alla posizione del cursore. Questo si applicherà quando gli utenti scorrono verso destra o sinistra. Quando gli utenti scorrono verso destra, recuperando più dati in background, riempiremo i dati grezzi ogni volta dopo aver ricevuto nuovi dati. Tuttavia, i dati grezzi non saranno coinvolti nel rendering della pagina.

Ecco come appare dopo il miglioramento:

Profilo della memoria

Diamo un'altra occhiata agli Strumenti per sviluppatori di Chrome. Come prima, la prima istantanea è stata scattata al momento dell'inizializzazione e la seconda dopo aver fatto scorrere la pagina verso destra 12 volte. Ora, caricare più di 100 elementi costa solo 0,3 MB di memoria in più, contro i 9,7 MB di prima.

Cosa ci aspetta?

Oltre a migliorare il componente carosello per gestire finestre di dati di grandi dimensioni, quando rifattoriamo una funzionalità/pagina, dobbiamo aggiungere ulteriori benchmark per acquisire le informazioni sulle prestazioni.

Sebbene lo stack delle moderne applicazioni web si stia spostando verso il front-end, acquisire e migliorare la telemetria del front-end è importante quanto la tradizionale telemetria del back-end.

Ying Jiang è Principal Frontend Software Engineer presso Roblox. In qualità di prima Frontend Engineer di Roblox, lavora per introdurre un moderno stack tecnologico frontend in Roblox e migliorare la pipeline di sviluppo e distribuzione. Ha inoltre lavorato su funzionalità in tempo reale quali chat, flusso di notifiche e voce.

Né Roblox Corporation né questo blog promuovono o sostengono alcuna azienda o servizio. Inoltre, non vengono fornite garanzie o promesse riguardo all'accuratezza, all'affidabilità o alla completezza delle informazioni contenute in questo blog.