Wenn Sie nicht dynamisch Scripts geladen werden oder markieren sie als defer
oder async
werden dann Skripts in der Reihenfolge , in der Seite aufgetreten geladen. Es spielt keine Rolle, ob es sich um ein externes Skript oder ein Inline-Skript handelt - sie werden in der Reihenfolge ausgeführt, in der sie auf der Seite vorkommen. Inline-Skripte, die nach externen Skripten kommen, werden gehalten, bis alle externen Skripte, die vor ihnen kamen, geladen und ausgeführt wurden.
Asynchrone Skripte (unabhängig davon, wie sie als asynchron angegeben werden) werden geladen und in einer unvorhersehbaren Reihenfolge ausgeführt. Der Browser lädt sie parallel und kann sie in beliebiger Reihenfolge ausführen.
Es gibt keine vorhersehbare Reihenfolge zwischen mehreren asynchronen Dingen. Wenn eine vorhersehbare Reihenfolge benötigt wird, muss diese codiert werden, indem für Ladebenachrichtigungen aus den asynchronen Skripten registriert und Javascript-Aufrufe manuell sequenziert werden, wenn die entsprechenden Dinge geladen werden.
Wenn ein Skript-Tag dynamisch eingefügt wird, hängt das Verhalten der Ausführungsreihenfolge vom Browser ab. In diesem Referenzartikel können Sie sehen, wie sich Firefox verhält . Kurz gesagt, die neueren Versionen von Firefox verwenden standardmäßig ein dynamisch hinzugefügtes Skript-Tag zu asynchron, sofern das Skript-Tag nicht anders festgelegt wurde.
Ein Skript-Tag mit async
kann ausgeführt werden, sobald es geladen wird. Tatsächlich kann der Browser den Parser von allen anderen Aktionen anhalten und das Skript ausführen. Es kann also wirklich fast jederzeit ausgeführt werden. Wenn das Skript zwischengespeichert wurde, wird es möglicherweise fast sofort ausgeführt. Wenn das Laden des Skripts eine Weile dauert, wird es möglicherweise ausgeführt, nachdem der Parser fertig ist. Das einzige, woran Sie sich erinnern sollten, async
ist, dass es jederzeit ausgeführt werden kann und diese Zeit nicht vorhersehbar ist.
Ein Skript-Tag mit defer
wartet, bis der gesamte Parser fertig ist, und führt dann alle Skripte aus, die mit defer
in der Reihenfolge markiert sind, in der sie angetroffen wurden. Auf diese Weise können Sie mehrere voneinander abhängige Skripte als markieren defer
. Sie werden alle verschoben, bis der Dokumentparser fertig ist, aber sie werden in der Reihenfolge ausgeführt, in der sie angetroffen wurden, wobei ihre Abhängigkeiten erhalten bleiben. Ich denke, defer
als würden die Skripte in eine Warteschlange gestellt, die nach Abschluss des Parsers verarbeitet wird. Technisch gesehen kann der Browser die Skripte jederzeit im Hintergrund herunterladen, aber sie werden den Parser erst ausführen oder blockieren, nachdem der Parser die Seite analysiert und Inline-Skripte analysiert und ausgeführt hat, die nicht markiert sind defer
oder async
.
Hier ist ein Zitat aus diesem Artikel:
In Skripte eingefügte Skripte werden asynchron in IE und WebKit ausgeführt, jedoch synchron in Opera und Firefox vor 4.0.
Der relevante Teil der HTML5-Spezifikation (für neuere kompatible Browser) ist hier . Dort ist viel über asynchrones Verhalten geschrieben. Offensichtlich gilt diese Spezifikation nicht für ältere Browser (oder fehlerhafte Browser), deren Verhalten Sie wahrscheinlich testen müssten, um festzustellen.
Ein Zitat aus der HTML5-Spezifikation:
Dann muss die erste der folgenden Optionen befolgt werden, die die Situation beschreiben:
Wenn das Element ein src-Attribut hat und das Element ein Defer-Attribut hat und das Element als "Parser-Insert" gekennzeichnet wurde und das Element kein asynchrones Attribut hat
, muss das Element am Ende der Liste von hinzugefügt werden Skripte, die ausgeführt werden, wenn das Parsen des Dokuments abgeschlossen ist, das dem Dokument des Parsers zugeordnet ist, der das Element erstellt hat.
Die Aufgabe, die die Quelle der Netzwerkaufgabe nach Abschluss des Abrufalgorithmus in die Aufgabenwarteschlange stellt, muss das Flag "Bereit zur Ausführung durch den Parser" des Elements setzen. Der Parser übernimmt die Ausführung des Skripts.
Wenn das Element ein src-Attribut hat und das Element als "Parser eingefügt" gekennzeichnet wurde und das Element kein asynchrones Attribut hat
Das Element ist das ausstehende Parsing-Blocking-Skript des Dokuments des Parsers, der das Element erstellt hat. (Es kann jeweils nur ein solches Skript pro Dokument vorhanden sein.)
Die Aufgabe, die die Quelle der Netzwerkaufgabe nach Abschluss des Abrufalgorithmus in die Aufgabenwarteschlange stellt, muss das Flag "Bereit zur Ausführung durch den Parser" des Elements setzen. Der Parser übernimmt die Ausführung des Skripts.
Wenn das Element kein Attribut src haben, und das Element markiert wurde als „Parser-eingefügt“ und das Dokument des HTML - Parser oder XML - Parser, der das Skript Element erstellt Blatt ein Stil, der Skripte blockiert Das Element ist die ausstehendes Parsing-Blocking-Skript des Dokuments des Parsers, der das Element erstellt hat. (Es kann jeweils nur ein solches Skript pro Dokument vorhanden sein.)
Setzen Sie das Flag "Bereit, vom Parser ausgeführt zu werden" des Elements. Der Parser übernimmt die Ausführung des Skripts.
Wenn das Element ein src-Attribut hat, kein asynchrones Attribut hat und das Flag "force-async" nicht gesetzt ist, muss das Element am Ende der Liste der Skripte hinzugefügt werden, die so schnell wie möglich ausgeführt werden mit dem Dokument des Skriptelements zum Zeitpunkt der Erstellung eines Skriptalgorithmus gestartet.
Die Aufgabe, die die Quelle der Netzwerkaufgabe nach Abschluss des Abrufalgorithmus in die Aufgabenwarteschlange stellt, muss die folgenden Schritte ausführen:
Wenn das Element jetzt nicht das erste Element in der Liste der Skripte ist, die in der Reihenfolge ausgeführt werden, in der es so schnell wie möglich hinzugefügt wurde, markieren Sie das Element als bereit, brechen Sie diese Schritte jedoch ab, ohne das Skript noch auszuführen.
Ausführung: Führen Sie den Skriptblock aus, der dem ersten Skriptelement in dieser Liste von Skripten entspricht, die so schnell wie möglich in der richtigen Reihenfolge ausgeführt werden.
Entfernen Sie das erste Element aus dieser Liste der Skripte, die so schnell wie möglich ausgeführt werden.
Wenn diese Liste der Skripte, die so schnell wie möglich in der richtigen Reihenfolge ausgeführt werden, noch nicht leer ist und der erste Eintrag bereits als fertig markiert wurde, kehren Sie zum Schritt mit der Bezeichnung Ausführung zurück.
Wenn das Element ein src-Attribut hat Das Element muss zu der Gruppe von Skripten hinzugefügt werden, die zum Zeitpunkt der Erstellung eines Skriptalgorithmus so schnell wie möglich im Dokument des Skriptelements ausgeführt werden.
Die Aufgabe, die die Quelle der Netzwerkaufgabe nach Abschluss des Abrufalgorithmus in die Aufgabenwarteschlange stellt, muss den Skriptblock ausführen und dann das Element aus dem Satz von Skripten entfernen, die so schnell wie möglich ausgeführt werden.
Andernfalls muss der Benutzeragent den Skriptblock sofort ausführen, auch wenn andere Skripte bereits ausgeführt werden.
Was ist mit Javascript-Modul-Skripten type="module"
?
Javascript unterstützt jetzt das Laden von Modulen mit folgender Syntax:
<script type="module">
import {addTextToBody} from './utils.mjs';
addTextToBody('Modules are pretty cool.');
</script>
Oder mit src
Attribut:
<script type="module" src="http://somedomain.com/somescript.mjs">
</script>
Alle Skripte mit type="module"
erhalten automatisch das defer
Attribut. Dadurch werden sie parallel (wenn nicht inline) zum anderen Laden der Seite heruntergeladen und anschließend in der angegebenen Reihenfolge ausgeführt, jedoch nachdem der Parser fertig ist.
Modulskripten kann auch das async
Attribut zugewiesen werden, mit dem Inline-Modulskripte so schnell wie möglich ausgeführt werden. Sie warten nicht, bis der Parser fertig ist, und warten nicht darauf, das async
Skript in einer bestimmten Reihenfolge im Vergleich zu anderen Skripten auszuführen .
Es gibt ein ziemlich nützliches Zeitdiagramm, das das Abrufen und Ausführen verschiedener Kombinationen von Skripten zeigt, einschließlich Modulskripten hier in diesem Artikel: Laden von Javascript- Modulen .