Ottimizza l'esecuzione di JavaScript

Spesso JavaScript attiva modifiche visive. A volte avviene direttamente attraverso manipolazioni di stile, mentre altre volte sono calcoli che comportano modifiche visive, come la ricerca o l'ordinamento dei dati. JavaScript a tempo limitato o a lunga esecuzione è una causa comune di problemi di prestazioni. Dove possibile, dovresti cercare di minimizzare il suo impatto.

Paul Lewis

Spesso JavaScript attiva modifiche visive. A volte è direttamente attraverso manipolazioni di stile; a volte sono i calcoli che comportano cambiamenti visivi, come la ricerca o l'ordinamento dei dati. Scadente oppure JavaScript a lunga esecuzione è una delle cause più comuni di problemi di prestazioni. Dove possibile, dovresti cercare di minimizzare il suo impatto.

La profilazione delle prestazioni JavaScript può essere un'opera d'arte, perché il codice JavaScript che scrivi niente come il codice che viene effettivamente eseguito. I browser moderni usano compilatori JIT e qualsiasi ottimizzazioni e trucchi per cercare di garantire l'esecuzione più rapida possibile. modifica sostanzialmente la dinamica del codice.

Detto questo, tuttavia, ci sono alcune cose che puoi sicuramente fare per aiutare le tue app a eseguire JavaScript.

Riepilogo

  • Evita setTimeout o setInterval per gli aggiornamenti visivi. usa sempre requestAnimationFrame.
  • Sposta il codice JavaScript a lunga esecuzione dal thread principale ai web worker.
  • Utilizza micro-attività per apportare modifiche al DOM su più frame.
  • Usa la funzionalità Spostamenti e JavaScript Profiler di Chrome DevTools per valutare l'impatto di JavaScript.

Usa requestAnimationFrame per le modifiche visive

Quando avvengono dei cambiamenti visivi sullo schermo, vuoi svolgere il tuo lavoro al momento giusto per all'inizio del frame. L'unico modo per garantire che il tuo codice JavaScript verrà eseguita all'inizio di un frame prevede l'uso di requestAnimationFrame.

/**
    * If run as a requestAnimationFrame callback, this
    * will be run at the start of the frame.
    */
function updateScreen(time) {
    // Make visual updates here.
}

requestAnimationFrame(updateScreen);

Framework o esempi possono utilizzare setTimeout o setInterval per apportare modifiche visive come animazioni, ma il problema è che il callback verrà eseguito in un punto del frame, probabilmente alla fine, e questo può spesso avere l'effetto di farci perdere un frame, causando jank.

setTimeout provoca la perdita di un frame da parte del browser.

Infatti, jQuery utilizzava setTimeout per il comportamento animate. È stato modificato requestAnimationFrame nella versione 3. Se utilizzi una versione precedente di jQuery, puoi applica una patch per utilizzare requestAnimationFrame, che è vivamente consigliato.

Riduci la complessità o utilizza i web worker

JavaScript viene eseguito nel thread principale del browser, accanto ai calcoli di stile, al layout e, in molti casi dipingere. Se il tuo codice JavaScript viene eseguito per molto tempo, bloccherà queste altre attività, causando la perdita di frame.

Bisogna essere tattici su quando viene eseguito JavaScript e per quanto tempo. Ad esempio, se ti trovi in una come lo scorrimento, dovresti cercare di mantenere il codice JavaScript in un valore regione di 3-4 ms. Se dura più a lungo, rischi di perdere troppo tempo. Se sei inattivo un periodo di tempo, puoi permetterti di concentrarti sul tempo impiegato.

In molti casi puoi spostare il lavoro puro computazionale Web worker, se, ad esempio, non richiede l'accesso al DOM. manipolazione o attraversamento dei dati. come l'ordinamento o la ricerca, sono spesso adatti a questo modello, così come il caricamento e la generazione del modello.

var dataSortWorker = new Worker("sort-worker.js");
dataSortWorker.postMesssage(dataToSort);

// The main thread is now free to continue working on other things...

dataSortWorker.addEventListener('message', function(evt) {
    var sortedData = evt.data;
    // Update data on screen...
});

Non tutto il lavoro è adatto a questo modello: i web worker non dispongono dell'accesso DOM. Nel caso in cui il tuo lavoro si trovi nel thread principale, prendi in considerazione un approccio in batch, in cui suddividi l'attività più grande in micro-attività, ciascuna che non richiede più di pochi millisecondi, e li esegui all'interno di gestori requestAnimationFrame in ogni frame.

Questo approccio comporta conseguenze a livello di UX e UI e dovrai assicurarti che l'utente sappia indica che un'attività è in fase di elaborazione utilizzando un indicatore di avanzamento o un indicatore di attività. In ogni caso, questo approccio manterrà senza costi il thread principale della tua app, in modo che possa rispondere rapidamente le interazioni degli utenti.

Conoscere la "tassa frame" del tuo JavaScript

Quando valuti un framework, una libreria o il tuo codice, è importante valutare quanto costa eseguire il codice JavaScript fotogramma per frame. Questo è particolarmente importante quando si eseguono animazioni in cui le prestazioni sono critiche per le prestazioni, per la transizione o lo scorrimento.

Il riquadro Prestazioni di Chrome DevTools è il modo migliore per misurare Costo di JavaScript. In genere si ottengono record di basso livello come questo:

Una registrazione delle prestazioni in Chrome DevTools

La sezione Principale fornisce un grafico a fiamme delle chiamate JavaScript in modo da possono analizzare esattamente quali funzioni sono state chiamate e quanto tempo ha impiegato.

Grazie a queste informazioni, puoi valutare l'impatto sul rendimento del JavaScript sulla tua applicazione e iniziare a trovare e correggere eventuali hotspot l'esecuzione delle funzioni sta richiedendo troppo tempo. Come detto in precedenza, dovresti cercare rimuovere il codice JavaScript a lunga esecuzione o, se non è possibile, spostarlo a un web worker, liberando il thread principale per continuare con altre attività.

Consulta la Guida introduttiva all'analisi delle prestazioni del runtime per informazioni su come utilizzare nel riquadro Prestazioni.

Evita di micro-ottimizzare JavaScript

Può essere interessante sapere che il browser può eseguire una versione delle cose 100 volte più velocemente un'altra cosa, ad esempio richiedere l'offsetTop di un elemento è più veloce rispetto al calcolo getBoundingClientRect(), ma è quasi sempre vero che chiamerai solo funzioni come un numero ridotto di volte per frame, quindi di solito è uno spreco di impegno concentrarci su questo aspetto le prestazioni di JavaScript. In genere, risparmierai solo frazioni di millisecondi.

Se stai creando un gioco o un'applicazione costosa dal punto di vista dell'elaborazione, probabilmente sei un'eccezione a questa guida, poiché in genere farai molti calcoli in un singolo frame. in questo caso tutto aiuta.

In breve, bisogna essere molto cauti delle micro-ottimizzazioni perché in genere non corrispondono di applicazione che stai creando.