Se non stai caricando dinamicamente gli script o contrassegnandoli come defer
o async
, gli script vengono caricati nell'ordine riscontrato nella pagina. Non importa se si tratta di uno script esterno o di uno script inline: vengono eseguiti nell'ordine in cui si trovano nella pagina. Gli script incorporati che seguono gli script esterni vengono conservati fino a quando tutti gli script esterni che li precedono non sono stati caricati ed eseguiti.
Gli script asincroni (indipendentemente dal modo in cui sono specificati come asincroni) vengono caricati ed eseguiti in un ordine imprevedibile. Il browser li carica in parallelo ed è gratuito eseguirli nell'ordine desiderato.
Non esiste un ordine prevedibile tra più cose asincrone. Se uno necessitava di un ordine prevedibile, dovrebbe essere codificato registrandosi per le notifiche di carico dagli script asincroni e sequenziando manualmente le chiamate javascript quando vengono caricate le cose appropriate.
Quando un tag di script viene inserito in modo dinamico, il comportamento dell'ordine di esecuzione dipenderà dal browser. Puoi vedere come si comporta Firefox in questo articolo di riferimento . In breve, le versioni più recenti di Firefox impostano in modo asincrono un tag di script aggiunto dinamicamente, a meno che il tag di script non sia stato impostato diversamente.
Un tag di script con async
può essere eseguito non appena viene caricato. In effetti, il browser potrebbe mettere in pausa il parser da qualsiasi altra cosa stesse facendo ed eseguire quello script. Quindi, può davvero funzionare in qualsiasi momento. Se lo script fosse memorizzato nella cache, potrebbe essere eseguito quasi immediatamente. Se il caricamento dello script richiede un po 'di tempo, potrebbe essere eseguito al termine dell'analisi. L'unica cosa da ricordare async
è che può funzionare in qualsiasi momento e che il tempo non è prevedibile.
Un tag di script defer
attende fino a quando non viene eseguito l'intero parser e quindi esegue tutti gli script contrassegnati defer
nell'ordine in cui sono stati rilevati. Ciò consente di contrassegnare diversi script che dipendono l'uno dall'altro defer
. Verranno tutti posticipati fino al termine dell'analisi del documento, ma verranno eseguiti nell'ordine in cui sono stati rilevati preservando le loro dipendenze. Penso che defer
gli script vengano rilasciati in una coda che verrà elaborata al termine dell'analisi. Tecnicamente, il browser potrebbe scaricare gli script in background in qualsiasi momento, ma non eseguiranno o bloccheranno il parser fino a quando il parser non avrà terminato l'analisi della pagina e l'analisi e l'esecuzione di eventuali script incorporati che non sono contrassegnati defer
o async
.
Ecco una citazione da quell'articolo:
gli script inseriti negli script vengono eseguiti in modo asincrono in IE e WebKit, ma in modo sincrono in Opera e Firefox precedente alla 4.0.
La parte pertinente delle specifiche HTML5 (per i browser più recenti conformi) è qui . C'è molto scritto lì sul comportamento asincrono. Ovviamente, questa specifica non si applica ai browser più vecchi (o browser non conformi) il cui comportamento dovresti probabilmente testare per determinare.
Un preventivo dalle specifiche HTML5:
Quindi, deve essere seguita la prima delle seguenti opzioni che descrive la situazione:
Se l'elemento ha un attributo src e l'elemento ha un attributo differito e l'elemento è stato contrassegnato come "inserito dal parser" e l'elemento non ha un attributo asincrono
L'elemento deve essere aggiunto alla fine dell'elenco di script che verranno eseguiti al termine dell'analisi del documento associato al documento del parser che ha creato l'elemento.
L'attività che l'origine dell'attività di rete inserisce nella coda delle attività una volta completato l'algoritmo di recupero deve impostare il flag "pronto per essere eseguito dal parser" dell'elemento. Il parser gestirà l'esecuzione dello script.
Se l'elemento ha un attributo src e l'elemento è stato contrassegnato come "inserito nel parser" e l'elemento non ha un attributo asincrono
L'elemento è lo script di blocco dell'analisi in sospeso del documento del parser che ha creato l'elemento. (Può esistere solo uno di questi script per documento alla volta).
L'attività che l'origine dell'attività di rete inserisce nella coda delle attività una volta completato l'algoritmo di recupero deve impostare il flag "pronto per essere eseguito dal parser" dell'elemento. Il parser gestirà l'esecuzione dello script.
Se l'elemento non ha un attributo src e l'elemento è stato contrassegnato come "inserito dal parser" e il documento del parser HTML o del parser XML che ha creato l'elemento script ha un foglio di stile che blocca gli script L'elemento è il script di blocco dell'analisi in sospeso del documento del parser che ha creato l'elemento. (Può esistere solo uno di questi script per documento alla volta).
Imposta il flag "pronto per essere eseguito dal parser" dell'elemento. Il parser gestirà l'esecuzione dello script.
Se l'elemento ha un attributo src, non ha un attributo asincrono e non ha il flag set "force-async" L'elemento deve essere aggiunto alla fine dell'elenco di script che verranno eseguiti nell'ordine associato il prima possibile con il documento dell'elemento script al momento in cui è stato avviato la preparazione di un algoritmo di script.
L'attività che l'origine dell'attività di rete inserisce nella coda delle attività una volta completato l'algoritmo di recupero deve eseguire i seguenti passaggi:
Se l'elemento non è ora il primo elemento nell'elenco di script che verrà eseguito nell'ordine il più presto possibile a cui è stato aggiunto sopra, quindi contrassegnare l'elemento come pronto ma interrompere questi passaggi senza eseguire ancora lo script.
Esecuzione: eseguire il blocco di script corrispondente al primo elemento di script in questo elenco di script che verrà eseguito nell'ordine il più presto possibile.
Rimuovi il primo elemento da questo elenco di script che verranno eseguiti nell'ordine il più presto possibile.
Se questo elenco di script che verranno eseguiti nell'ordine il più presto possibile non è ancora vuoto e la prima voce è già stata contrassegnata come pronta, tornare indietro al passaggio contrassegnato come esecuzione.
Se l'elemento ha un attributo src L'elemento deve essere aggiunto al set di script che verrà eseguito il prima possibile del documento dell'elemento script nel momento in cui è stato avviato un algoritmo di preparazione dello script.
L'attività che l'origine dell'attività di rete inserisce nella coda delle attività una volta completato l'algoritmo di recupero deve eseguire il blocco di script e quindi rimuovere l'elemento dal set di script che verrà eseguito il prima possibile.
In caso contrario, l'agente utente deve eseguire immediatamente il blocco di script, anche se altri script sono già in esecuzione.
Che dire degli script del modulo Javascript type="module"
?
Javascript ora supporta il caricamento del modulo con sintassi come questa:
<script type="module">
import {addTextToBody} from './utils.mjs';
addTextToBody('Modules are pretty cool.');
</script>
Oppure, con src
attributo:
<script type="module" src="http://somedomain.com/somescript.mjs">
</script>
A tutti gli script con type="module"
viene assegnato automaticamente l' defer
attributo. Questo li scarica in parallelo (se non in linea) con altri caricamenti della pagina e quindi li esegue in ordine, ma al termine dell'analisi.
Agli script del modulo può anche essere assegnato l' async
attributo che eseguirà gli script del modulo in linea il più presto possibile, senza attendere il completamento del parser e non attendere l'esecuzione dello async
script in un ordine particolare rispetto ad altri script.
C'è un diagramma temporale piuttosto utile che mostra il recupero e l'esecuzione di diverse combinazioni di script, inclusi gli script del modulo qui in questo articolo: Caricamento del modulo Javascript .