Können Sie die Attribute async und defer für ein HTML-Skript-Tag verwenden?

78

Ich möchte den folgenden JavaScript-Code mit beiden deferund laden async:

<script defer async src="/js/somescript.js"></script>

Da deferInternet Explorer 5.5+ unterstützt wird, wie Sie auf CanIUse.com sehen können , möchte ich auf die Verwendung von Defer zurückgreifen , wenn Async nicht verfügbar ist. Async ist meiner Meinung nach besser zu verwenden, wenn es verfügbar ist, wird aber erst mit Internet Explorer 10 unterstützt.

Meine Frage ist daher, ob der obige Code gültiges HTML ist. Wenn nicht, ist es möglich, diese Situation mit JavaScript zu erstellen und auf die Verwendung deferin einem Skript zurückzugreifen, wenn asynces nicht verfügbar ist?

Jasdeep Khalsa
quelle

Antworten:

124

Aus der Spezifikation: https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async

Das Defer-Attribut kann auch dann angegeben werden, wenn das Async-Attribut angegeben ist, damit ältere Webbrowser, die nur Defer (und nicht Async) unterstützen, auf das Defer-Verhalten anstelle des standardmäßigen synchronen Blockierungsverhaltens zurückgreifen.

Dave
quelle
5
Ist das wahr?: 1. Beide async deferexistieren, moderne Browser laufen wie async; 2.Beide async deferexistieren, alte Browser laufen wie deferanstelle von defaultVerhalten
Vikyd
Tun Async und Defer nicht das Gegenteil? Async lädt das Skript gleichzeitig, wird jedoch ausgeführt, wenn der Ladevorgang abgeschlossen ist (Pause beim Parsen der Seite). Defer wird jedoch erst am Ende des gesamten Ladens und Parsens ausgeführt.
Leo Müller
3
Wenn das asynchrone Attribut vorhanden ist, wird das Skript asynchron ausgeführt, sobald es verfügbar ist. Wenn das asynchrone Attribut nicht vorhanden ist, das verzögerte Attribut jedoch vorhanden ist, wird das Skript ausgeführt, wenn die Analyse der Seite abgeschlossen ist. In beiden Fällen wird das Laden von Seiten nicht blockiert.
Dave
@LeoMuller Deshalb heißt es "Fallback". Moderne diejenigen bevorzugen asynczu defer. Und ein Ja zu @vikyd. Wenn Sie sich nur nicht um das Erbe kümmern, möchten Sie niemals beide auf einem haben <script>.
Константин Ван
18

Die Frage ist, was würden Sie davon erwarten? Wenn beide async und defer vorhanden sind , würde ich das Skript erwartet verschoben werden und erst nach DOMContentLoaded ausgeführt , wenn der Browser im Leerlauf ist, aber wenn ich die Spezifikation richtig gerade lese es sieht aus wie defer ignoriert, wenn async gesetzt wird und das Skript geladen asynchron, wird also ausgeführt, sobald es verfügbar ist. Dies kann durchaus vor DOMContentLoaded liegen und andere Ressourcen blockieren.

Es gibt drei mögliche Modi, die mit diesen Attributen ausgewählt werden können. Wenn das asynchrone Attribut vorhanden ist, wird das Skript asynchron ausgeführt, sobald es verfügbar ist. Wenn das asynchrone Attribut nicht vorhanden ist, das verzögerte Attribut jedoch vorhanden ist, wird das Skript ausgeführt, wenn die Analyse der Seite abgeschlossen ist. Wenn keines der Attribute vorhanden ist, wird das Skript sofort abgerufen und ausgeführt, bevor der Benutzeragent die Seite weiter analysiert.

https://www.w3.org/TR/2011/WD-html5-20110525/scripting-1.html#attr-script-async

Patrick Clancey
quelle
10

Wird leider deferignoriert, wenn asyncangegeben, und hat asyncimmer eine höhere Priorität. (Zumindest in Chrome. Ehrlich gesagt, nicht in anderen Browsern getestet, aber ich denke, dass das Ergebnis das gleiche sein wird.)

Und ich persönlich finde es sehr schlimm, dass deferes ignoriert wird. Stellen wir uns eine Situation vor, in der JS so schnell wie möglich initialisiert werden soll, noch bevor der Seiteninhalt geladen wird. Wir möchten jedoch, dass dieses Skript VOR den restlichen Skripten initialisiert wird, für die dies erforderlich ist. Es sollte zuerst in der deferWarteschlange stehen. Aber das wird leider nicht funktionieren:

<!-- we want "jQuery" ASAP and still in "defer" queue. But defer is ignored. -->
<script src="jquery.min.js" async defer></script>

<!-- this doesn't blocks the content and can wait the full page load, but requires "jQuery" -->
<script src="some_jquery_plugin.min.js" defer></script>

In diesem Beispiel kann "some_jquery_plugin.min.js" vor dem Laden von jQuery geladen und ausgeführt werden und schlägt fehl. :(

Es gibt also zwei Möglichkeiten, um das Problem zu lösen: Verwenden Sie entweder nur die deferDirektive oder führen Sie alle abhängigen Javascript-Dateien zu einem einzigen JS zusammen.

Aleksey Kuznetsov
quelle
9

Ja, es ist gültiges HTML und es wird wie erwartet funktionieren.

Jeder W3C-kompatible Browser erkennt das asynchrone Attribut und behandelt das Skript ordnungsgemäß, während ältere IE- Versionen das verzögerte Attribut erkennen.

Da beide Attribute sind boolean nicht wahr haben einen Wert zuweisen.

jAndy
quelle
Danke @jandy für eine weitere tolle Antwort!
Jasdeep Khalsa
11
"... wird wie erwartet funktionieren." Was würden Sie davon erwarten?!
Patrick Clancey