• cerca

SEI GIA' REGISTRATO? EFFETTUA ADESSO IL LOGIN.



HAI DIMENTICATO LA PASSWORD? CLICCA QUI

NON SEI ANCORA REGISTRATO A WEBAREA? CLICCA QUI E REGISTRATI !

Esecuzione controllata di JavaScript: Asynchronous vs Deferred

di :: 10 febbraio 2018

javascript defer async

Come sapete, le pagine web, cioè i documenti HTML, vengono letti e analizzati ("parsing") dalla apertura dell'elemento <html> alla sua chiusura </html>.
JavaScript è considerata una risorsa "parser blocking": quando il parser del browser legge il codice HTML e incontra uno script, sospende tutte le operazioni per recuperare lo script (se è esterno) ed eseguirlo, per poi riprendere il parsing. Alla fine di tutto questo processo viene renderizzata la pagina, cioè visualizzata.

Questo comportamento può essere problematico se stiamo caricando diversi file JavaScript su una pagina, in quanto ciò comporterà un aumento dei tempi di caricamento (rendering) della pagina stessa, a maggior ragione se lo script è esterno e va recuperato.

Questo un esempio di script esterno, cioè di script presente in un file esterno alla pagina web

<script type="text/javascript" src="ilmioscript.js"></script>

In questo caso il browser interrompe il parsing, scarica lo script, lo esegue, e solo alla fine riprende il parsing.

In questo secondo esempio vediamo uno script "in linea" cioè il cui codice è inserito direttamente nella pagina web (consigliato solo per piccoli script)

<script type="text/javascript">
/* il mio codice javascript */
</script>

In questo caso il browser interrompe il parsing, esegue il codice, e infine riprende il parsing.

Questa attesa per il dowload e per l'esecuzione di script può rallentare il caricamento della pagina.

Nel caso di script esterni, e solo per questi, l'elemento <script> ha due attributi, async e defer, che ci aiutano a controllarne il loro download ed esecuzione.

Attributo Async

Quando il parser HTML incontra uno script con attributo async, non viene sospenso il rendering dell’HTML, ma continua, mentre in parallelo viene effettuato il download dello script.
A download ultimato il parsing viene interrotto, e viene eseguito lo script
Ad esecuzione esecuzione completata dello script stesso, il parsing riprende.

Ecco un esempio di implementazione dell’attributo async:

<script src="ilmioscript.js" async></script>

Un esempio di async noto è lo script di Google Analytics

<script async src="https://www.googletagmanager.com/gtag/js?id=....."></script>

Nota: in presenza di più script async successivi, l’attributo async non garantisce che lo script venga eseguito nell’ordine in cui si trova all’interno della pagina HTML 
Infatti viene sempre eseguito quello che per primo viene scaricato, cioè quello il cui download si è rivelato essere più veloce.
Questo significa che l’attributo async non va mai usato per script che dipendono da altri script "parent", perchè non possiamo esser certi che lo script "parent" sia già stato caricato.

Attributo Defer

Ecco un esempio di implementazione dell’attributo defer:

<script src="ilmioscript.js" defer></script>

In presenza di questo attributo, a differenza di quanto avviene con l'attributo async, il parsing non viene messo in pausa. La pagina prima viene "parsata", poi "renderizzata" (visualizzata) e solo adesso vengono eseguiti gli script rispettando l'ordine in cui sono presenti all’interno della pagina HTML.
Per esser tecnicamente più corretti, il codice Javascript defer viene eseguito al verificarsi dell’evento DOM interactive ma prima del DOMContentLoaded. 

Async e Defer o ... esecuzione normale?

Cosa scegliere tra questi due attributi, o il loro non utilizzo? La risposta come sempre è: dipende.

  1. Dove si trova l'elemento script?
    Se un JavaScript viene posizionato a fondo pagina, quindi subito prima dell'elemento </body> di chiusura, diventa MENO UTILE utilizzare un attributo async o defer. Dal momento infatti che il parsing sarà praticamente ultimato, lo script non sarà bloccante. Quindi questi due attributi sono importanti quando l'elemento <script> NON si trova alla fine del documento.
  2. Lo script è autonomo o dipende da altri script?
    Per script che NON dipendono da altri script, e che non sono necessari per la costruzione del codice della pagina (come ad esempio lo script di Google Analytics), l'attributo async è particolarmente utile.
  3. Lo script serve per la costruzione della pagina?
    In molti casi, il file di script contiene funzionalità che richiedono l'interazione con il DOM (con la pagina) e quindi è necessario il parsing completo prima di eseguire lo script.
    In questo caso tale file dovrebbe essere posizionato nella parte inferiore della pagina per garantire tutto prima che sia stato analizzato.
    Tuttavia, se, per qualsiasi motivo, il file in questione deve essere collocato altrove, è possibile utilizzare l'attributo defer.
  4. Che dimensione ha lo script?
    Se lo script è relativamente piccolo, e non dipende altri file, potrebbe essere più utile inserirlo "in linea" cioè direttamente nella pagina anzichè caricarlo esternamente, senza quindi utilzzare async e defer. 
    Anche se questo bloccherà il parsing del documento HTML, non dovrebbe essere un'interferenza significativa se è di piccole dimensioni.

In generale, gli script caricati con defer non influiscono minimamente al parsing del codice HTML e al rendering della pagina, mentre gli script async potrebbero.
Infatti se il download di uno script async termina prima del completamento del DOM, il parser HTML viene momentaneamente bloccato per eseguire il codice.

Google e velocità di caricamento delle pagine

La tendenza di Google negli ultimi anni è quella di prediligere i siti dal caricamento veloce, e di penalizzare i siti troppo lenti. 
Per questo motivo la velocità è uno degli elementi da ottimizzare in ottica SEO (Search Engine Optimization) per salire nelle posizioni (SERP) di Google. Un sito lento è a rischio penalizzazione e quindi è destinato a scendere nelle SERP.

Se provate a testare la velocità del vostro sito sul tool PageSpeed di Google, potreste incappare nel suggerimento per l'ottimizzazione "Elimina JavaScript e CSS che bloccano la visualizzazione nei contenuti above-the-fold".

I contenuti "above the fold" sono i primi elementi della pagina web che vengono visualizzati, cioè sono quelli che riescono a riempire lo schermo del monitor, o del device mobile, dell’utente, senza che questo debba fare alcun movimento di scroll nella pagina. Ecco che google ci sta suggerendo di rimandare (defer) o caricare in modo asincrono (async) script non utili alla visualzzazione della pagina, così da velocizzarne il rendering.

Approfondimenti

x

ATTENZIONE