• Die Position ist wichtig
  • Async und Defer
  • Leistungsvergleich
    • Kein defer oder async, in the head
    • Kein defer oder async, in the body
    • Mit async, in the head
    • Mit defer, im Kopf
  • Parsing blockieren
  • Rendering blockieren
  • domInteractive
  • Die Dinge in Ordnung halten
  • Sagen Sie mir einfach, wie es am besten geht

Wenn man ein Skript auf einer HTML-Seite lädt, muss man darauf achten, die Ladeleistung der Seite nicht zu beeinträchtigen.

Ein Skript wird traditionell auf diese Weise in die Seite eingebunden:

<script src="https://flaviocopes.com/javascript-async-defer/script.js"></script>

Wenn der HTML-Parser diese Zeile findet, wird eine Anfrage gestellt, um das Skript zu holen, und das Skript wird ausgeführt.

Wenn dieser Vorgang abgeschlossen ist, kann das Parsen fortgesetzt und der Rest des HTML-Skripts analysiert werden.

Wie Sie sich vorstellen können, kann dieser Vorgang einen großen Einfluss auf die Ladezeit der Seite haben.

Wenn das Skript etwas länger zum Laden braucht als erwartet, z. B. wenn das Netzwerk etwas langsam ist oder wenn Sie sich auf einem mobilen Gerät befinden und die Verbindung etwas schlampig ist, wird der Besucher wahrscheinlich eine leere Seite sehen, bis das Skript geladen und ausgeführt wird.

Auf die Position kommt es an

Wenn man HTML zum ersten Mal lernt, erfährt man, dass Skript-Tags im <head>-Tag untergebracht sind:

<html> <head> <title>Title</title> <script src="https://flaviocopes.com/javascript-async-defer/script.js"></script> </head> <body> ... </body></html>

Wie ich bereits sagte, wenn der Parser diese Zeile findet, holt er das Skript und führt es aus. Nachdem er diese Aufgabe erledigt hat, fährt er mit dem Parsen des Textkörpers fort.

Das ist schlecht, weil es zu einer großen Verzögerung kommt. Eine sehr verbreitete Lösung für dieses Problem ist es, den script-Tag am Ende der Seite zu platzieren, direkt vor dem schließenden </body>-Tag.

Damit wird das Skript geladen und ausgeführt, nachdem die Seite bereits geparst und geladen wurde, was eine enorme Verbesserung gegenüber der head-Alternative ist.

Das ist das Beste, was Sie tun können, wenn Sie ältere Browser unterstützen müssen, die zwei relativ neue Funktionen von HTML nicht unterstützen: async und defer.

Async und Defer

Beide, async und defer, sind boolesche Attribute. Ihre Verwendung ist ähnlich:

<script async src="https://flaviocopes.com/javascript-async-defer/script.js"></script>
<script defer src="https://flaviocopes.com/javascript-async-defer/script.js"></script>

Wenn Sie beide angeben, hat async auf modernen Browsern Vorrang, während ältere Browser, die defer aber nicht async unterstützen, auf defer zurückgreifen.

Diese Attribute sind nur sinnvoll, wenn das Skript im head-Teil der Seite verwendet wird, und sie sind nutzlos, wenn Sie das Skript in der body-Fußzeile platzieren, wie wir oben gesehen haben.

Leistungsvergleich

Kein defer oder async, im Kopfbereich

So lädt eine Seite ein Skript ohne defer oder async, das im headTeil der Seite steht:

Das Parsing wird angehalten, bis das Skript abgerufen und ausgeführt wurde. Sobald dies geschehen ist, wird das Parsen fortgesetzt.

Ohne defer oder async, im Body

So lädt eine Seite ein Skript ohne defer oder async, das am Ende des body-Tags steht, kurz bevor sie geschlossen wird:

Das Parsen wird ohne Pausen durchgeführt, und wenn es beendet ist, wird das Skript abgerufen und ausgeführt. Das Parsing wird durchgeführt, bevor das Skript überhaupt heruntergeladen wird, so dass die Seite dem Benutzer weit vor dem vorherigen Beispiel angezeigt wird.

Mit async, im Kopf

So lädt eine Seite ein Skript mit async, das im head-Tag steht:

Das Skript wird asynchron abgerufen, und wenn es fertig ist, wird das HTML-Parsing angehalten, um das Skript auszuführen, und dann wieder fortgesetzt.

Mit defer, im head

So lädt eine Seite ein Skript mit defer, eingefügt in den head-Tag:

Das Skript wird asynchron abgerufen, und es wird erst ausgeführt, wenn das HTML-Parsing abgeschlossen ist.

Das Parsen endet genauso, wie wenn wir das Skript an das Ende des body-Tags setzen, aber insgesamt endet die Skriptausführung deutlich früher, da das Skript parallel zum HTML-Parsen heruntergeladen wurde.

Das ist also die beste Lösung in Bezug auf die Geschwindigkeit 🏆

Parsing blockieren

async blockiert das Parsen der Seite, defer hingegen nicht.

Rendering blockieren

Weder async noch defer garantieren irgendetwas beim Blockieren des Renderings. Das liegt an dir und deinem Skript (zum Beispiel, indem du sicherstellst, dass deine Skripte nach dem onLoad-Ereignis ausgeführt werden).

domInteractive

Skripte, die mit defer gekennzeichnet sind, werden direkt nach dem domInteractive-Ereignis ausgeführt, was geschieht, nachdem das HTML geladen, geparst und das DOM aufgebaut wurde.

CSS und Bilder müssen zu diesem Zeitpunkt noch geparst und geladen werden.

Wenn dies geschehen ist, gibt der Browser das domComplete-Ereignis aus, und dann onLoad.

domInteractive ist wichtig, weil sein Timing als Maß für die wahrgenommene Ladegeschwindigkeit anerkannt wird. Siehe MDN für mehr.

Die Dinge in Ordnung halten

Ein weiterer Fall pro defer: Skripte, die mit async markiert sind, werden in zufälliger Reihenfolge ausgeführt, wenn sie verfügbar sind. Die mit defer gekennzeichneten Skripte werden (nach Abschluss des Parsings) in der Reihenfolge ausgeführt, in der sie im Markup definiert sind.

Sagen Sie mir einfach, wie es am besten geht

Das Beste, was Sie tun können, um das Laden Ihrer Seite zu beschleunigen, wenn Sie Skripte verwenden, ist, sie in den head zu setzen und ein defer-Attribut zu Ihrem script-Tag hinzuzufügen:

<script defer src="https://flaviocopes.com/javascript-async-defer/script.js"></script>

Dies ist das Szenario, das das schnellere domInteractive-Ereignis auslöst.

Abgesehen von den Vorteilen von defer scheint es in einer Reihe von Szenarien die bessere Wahl gegenüber async zu sein.

Wenn Sie nicht damit einverstanden sind, das erste Rendern der Seite zu verzögern, stellen Sie sicher, dass das gewünschte JavaScript bereits ausgeführt wird, wenn die Seite geparst wird.

Laden Sie mein kostenloses JavaScript-Handbuch für Anfänger herunter

Weitere Browser-Tutorials:

  • Einige nützliche Tricks in HTML5
  • Wie ich eine CMS-basierte Website offline zum Laufen gebracht habe
  • Der komplette Leitfaden für Progressive Web Apps
  • Die Fetch-API
  • Die Push-API-Anleitung
  • Die Channel Messaging API
  • Service Workers Tutorial
  • Das Cache-API-Leitfaden
  • Das Benachrichtigungs-API-Leitfaden
  • Einstieg in IndexedDB
  • Die Selectors API: querySelector und querySelectorAll
  • JavaScript effizient laden mit defer und async
  • Das Document Object Model (DOM)
  • Die Web Storage API: Lokaler Speicher und Sitzungsspeicher
  • Lernen, wie HTTP-Cookies funktionieren
  • Die History API
  • Das WebP-Bildformat
  • XMLHttpRequest (XHR)
  • Ein ausführliches SVG-Tutorial
  • Was sind Daten-URLs
  • Roadmap zum Erlernen der Web-Plattform
  • CORS, Cross-Origin Resource Sharing
  • Web Workers
  • Die requestAnimationFrame() Anleitung
  • Was ist der Doctype
  • Arbeiten mit der DevTools Konsole und der Konsolen-API
  • Die Sprachsynthese-API
  • Wie wartet man auf das DOM ready-Ereignis in einfachem JavaScript
  • Wie fügt man eine Klasse zu einem DOM Element
  • Wie man eine Schleife über DOM-Elemente aus querySelectorAll macht
  • Wie man eine Klasse aus einem DOM-Element entfernt
  • Wie man prüft, ob ein DOM-Element eine Klasse hat
  • Wie man einen DOM-Knotenwert ändert
  • Wie man ein Klick-Ereignis zu einer Liste von DOM-Elementen hinzufügt, die von querySelectorAll zurückgegeben wird
  • WebRTC, die Real Time Web API
  • Wie man die Scroll-Position eines Elements in JavaScript ermittelt
  • Wie man ein DOM-Element ersetzt
  • Wie man nur Bilder in einem Eingabefeld akzeptiert
  • Warum eine Vorschauversion eines Browsers verwenden?
  • Das Blob-Objekt
  • Das File-Objekt
  • Das FileReader-Objekt
  • Das FileList-Objekt
  • ArrayBuffer
  • ArrayBufferView
  • Das URL-Objekt
  • Typ. Arrays
  • Das DataView-Objekt
  • Die BroadcastChannel-API
  • Die Streams-API
  • Das FormData-Objekt
  • Das Navigator-Objekt
  • Wie man die Geolocation-API verwendet
  • Wie man getUserMedia()
  • Wie man die Drag and Drop API verwendet
  • Wie man mit Scrolling auf Webseiten arbeitet
  • Verarbeitung von Formularen in JavaScript
  • Tastaturereignisse
  • Maus Events
  • Touch Events
  • Wie entfernt man alle Kinder aus einem DOM-Element
  • Wie erstellt man ein HTML-Attribut mit Vanilla Javascript
  • Wie prüft man mit JavaScript, ob ein Kontrollkästchen markiert ist?
  • Wie kopiere ich mit JavaScript in die Zwischenablage
  • Wie deaktiviere ich mit JavaScript eine Schaltfläche
  • Wie mache ich eine Seite im Browser editierbar
  • Wie wie man Query-String-Werte in JavaScript mit URLSearchParams erhält
  • Wie man alle CSS von einer Seite auf einmal entfernt
  • Wie man insertAdjacentHTML verwendet
  • Safari, Warnung vor dem Beenden
  • Wie man ein Bild mit JavaScript zum DOM hinzufügt
  • Wie man ein Formular zurücksetzt
  • Wie man Google Fonts verwendet

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.