Frage Wo sollte ich

Wenn Sie JavaScript in ein HTML - Dokument einbetten, wo ist der richtige Ort, um den <script> Tags und enthaltenes JavaScript? Ich erinnere mich, dass Sie diese nicht in die <head> Abschnitt, sondern am Anfang der <body> Der Abschnitt ist auch schlecht, da das JavaScript analysiert werden muss, bevor die Seite komplett gerendert wird (oder so ähnlich). Dies scheint das zu verlassen Ende des <body> Abschnitt als logischer Ort für <script> Stichworte.

Also wo ist der richtige Ort, um die <script> Stichworte?

(Diese Frage verweist auf diese Frage, in dem vorgeschlagen wurde, dass JavaScript-Funktionsaufrufe von verschoben werden sollten <a> Tags zu <script> Stichworte. Ich verwende speziell jQuery, aber allgemeinere Antworten sind auch angebracht.)


1154
2018-01-12 18:15


Ursprung


Antworten:


Folgendes passiert, wenn ein Browser eine Website mit einem lädt <script> Etikett drauf:

  1. Holen Sie die HTML-Seite (z. B. index.html)
  2. Beginnen Sie mit der Analyse des HTML
  3. Der Parser trifft auf a <script> Tag, der auf eine externe Skriptdatei verweist.
  4. Der Browser fordert die Skriptdatei an. Währenddessen blockiert der Parser und hört auf, den anderen HTML-Code auf Ihrer Seite zu analysieren.
  5. Nach einiger Zeit wird das Skript heruntergeladen und anschließend ausgeführt.
  6. Der Parser analysiert den Rest des HTML-Dokuments weiter.

Schritt 4 verursacht eine schlechte Benutzererfahrung. Ihre Website wird grundsätzlich nicht mehr geladen, bis Sie alle Skripts heruntergeladen haben. Wenn es eine Sache gibt, die Benutzer hassen, wartet sie darauf, dass eine Website geladen wird.

Warum passiert das überhaupt?

Jedes Skript kann seinen eigenen HTML-Code einfügen document.write() oder andere DOM-Manipulationen. Dies bedeutet, dass der Parser warten muss, bis das Skript heruntergeladen und ausgeführt wurde, bevor es den Rest des Dokuments sicher analysieren kann. Immerhin das Skript könnte habe ein eigenes HTML in das Dokument eingefügt.

Die meisten JavaScript-Entwickler bearbeiten das DOM jedoch nicht mehr während Das Dokument wird geladen. Stattdessen warten sie, bis das Dokument geladen wurde, bevor es geändert wird. Beispielsweise:

<!-- index.html -->
<html>
    <head>
        <title>My Page</title>
        <script type="text/javascript" src="my-script.js"></script>
    </head>
    <body>
        <div id="user-greeting">Welcome back, user</div>
    </body>
</html>

Javascript:

// my-script.js
document.addEventListener("DOMContentLoaded", function() { 
    // this function runs when the DOM is ready, i.e. when the document has been parsed
    document.getElementById("user-greeting").textContent = "Welcome back, Bart";
});

Da Ihr Browser nicht weiß, dass my-script.js das Dokument erst ändert, wenn es heruntergeladen und ausgeführt wurde, hört der Parser auf zu analysieren.

Antiquierte Empfehlung

Der alte Ansatz, dieses Problem zu lösen, war zu setzen <script> Tags an der Unterseite Ihres <body>, weil dadurch sichergestellt wird, dass der Parser nicht bis zum Ende blockiert ist.

Dieser Ansatz hat sein eigenes Problem: Der Browser kann nicht mit dem Herunterladen der Skripts beginnen, bis das gesamte Dokument geparst ist. Bei größeren Websites mit großen Scripts und Stylesheets ist es sehr wichtig, dass Sie das Skript so schnell wie möglich herunterladen können. Wenn Ihre Website nicht innerhalb von 2 Sekunden geladen wird, werden die Leute auf eine andere Website gehen.

In einer optimalen Lösung würde der Browser beginnen, Ihre Skripte so schnell wie möglich herunterzuladen, während gleichzeitig der Rest Ihres Dokuments analysiert wird.

Der moderne Ansatz

Heute unterstützen Browser die async und defer Attribute für Skripts. Diese Attribute teilen dem Browser mit, dass das Analysieren während des Herunterladens der Skripts sicher fortgesetzt werden kann.

asynchron

<script type="text/javascript" src="path/to/script1.js" async></script>
<script type="text/javascript" src="path/to/script2.js" async></script>

Skripte mit dem Async-Attribut werden asynchron ausgeführt. Dies bedeutet, dass das Skript ausgeführt wird, sobald es heruntergeladen wird, ohne den Browser in der Zwischenzeit zu blockieren.
Dies bedeutet, dass es möglich ist, dass Skript 2 vor Skript 1 heruntergeladen und ausgeführt wird.

Gemäß http://caniuse.com/#feat=script-async94,57% aller Browser unterstützen dies.

verschieben

<script type="text/javascript" src="path/to/script1.js" defer></script>
<script type="text/javascript" src="path/to/script2.js" defer></script>

Skripte mit dem Defer-Attribut werden der Reihe nach ausgeführt (d. H. Erstes Skript 1, dann Skript 2). Dies blockiert auch nicht den Browser.

Im Gegensatz zu asynchronen Skripten werden Deferrer-Skripte nur ausgeführt, nachdem das gesamte Dokument geladen wurde.

Gemäß http://caniuse.com/#feat=script-defer94,59% aller Browser unterstützen dies. 94.92% unterstützen es zumindest teilweise.

Eine wichtige Anmerkung zur Browser-Kompatibilität: unter bestimmten Umständen kann IE <= 9 verzögerte Skripte in der falschen Reihenfolge ausführen. Wenn Sie diese Browser unterstützen müssen, lesen Sie bitte Dies zuerst!

Fazit

Der aktuelle Stand der Technik besteht darin, Skripte in die <head> Markieren und verwenden Sie die async oder defer Attribute. Dadurch können Ihre Skripte so schnell wie möglich heruntergeladen werden, ohne Ihren Browser zu blockieren.

Die gute Sache ist, dass Ihre Website immer noch korrekt auf den 6% der Browser geladen werden sollte, die diese Attribute nicht unterstützen, während die anderen 94% beschleunigt werden.


1464
2018-06-05 21:20



Kurz vor dem schließenden Body-Tag, wie auf

http://developer.yahoo.com/performance/rules.html#js_bottom

Scripte am unteren Rand platzieren

Das Problem von Skripten ist, dass sie parallele Downloads blockieren. Die HTTP / 1.1-Spezifikation schlägt vor, dass Browser pro Hostname nicht mehr als zwei Komponenten parallel herunterladen. Wenn Sie Ihre Bilder aus mehreren Hostnamen bereitstellen, können Sie mehr als zwei Downloads gleichzeitig durchführen. Während ein Skript heruntergeladen wird, startet der Browser keine anderen Downloads, auch nicht bei verschiedenen Hostnamen.


218
2018-01-12 18:18



Nicht blockierende Skript-Tags können überall platziert werden:

<script src="script.js" async></script>
<script src="script.js" defer></script>
<script src="script.js" async defer></script>
  • async Das Skript wird asynchron ausgeführt, sobald es verfügbar ist
  • defer Skript wird ausgeführt, wenn das Dokument mit dem Parsen fertig ist
  • async defer Das Skript greift auf das Zurückstellungsverhalten zurück, wenn Async nicht unterstützt wird

Solche Skripte werden asynchron / nach der Dokumentbereitstellung ausgeführt, was bedeutet, dass Sie dies nicht tun können:

<script src="jquery.js" async></script>
<script>jQuery(something);</script>
<!--
  * might throw "jQuery is not defined" error
  * defer will not work either
-->

Oder dieses:

<script src="document.write(something).js" async></script>
<!--
  * might issue "cannot write into document from an asynchronous script" warning
  * defer will not work either
-->

Oder dieses:

<script src="jquery.js" async></script>
<script src="jQuery(something).js" async></script>
<!--
  * might throw "jQuery is not defined" error (no guarantee which script runs first)
  * defer will work in sane browsers
-->

Oder dieses:

<script src="document.getElementById(header).js" async></script>
<div id="header"></div>
<!--
  * might not locate #header (script could fire before parser looks at the next line)
  * defer will work in sane browsers
-->

Asynchrone Skripts bieten diese Vorteile:

  • Paralleler Download von Ressourcen:
    Der Browser kann Stylesheets, Bilder und andere Skripte parallel herunterladen, ohne darauf warten zu müssen, dass ein Skript heruntergeladen und ausgeführt wird.
  • Unabhängigkeit der Quellreihenfolge:
    Sie können die Skripte in Kopf oder Körper platzieren, ohne sich Gedanken über das Blockieren machen zu müssen (nützlich, wenn Sie einen CMS verwenden). Die Ausführungsreihenfolge spielt dennoch eine Rolle.

Sie können die Ausführungsreihenfolge umgehen, indem Sie externe Skripts verwenden, die Rückrufe unterstützen. Viele JavaScript-APIs von Drittanbietern unterstützen jetzt die blockierungsfreie Ausführung. Hier ist ein Beispiel von Laden der Google Maps-API asynchron.


56
2018-02-06 11:19



Der Standard-Rat, der von der Yahoo! Außergewöhnliches Leistungsteam, ist das zu setzen <script> Tags am Ende des Dokumentkörpers, damit sie das Rendern der Seite nicht blockieren.

Aber es gibt einige neuere Ansätze, die eine bessere Leistung bieten, wie in diese Antwort über die Ladezeit der Google Analytics JavaScript-Datei:

Dort sind einige tolle Dias von Steve Souders (clientseitiger Performance-Experte) über:

  • Verschiedene Techniken, um externe JavaScript-Dateien parallel zu laden
  • ihre Auswirkung auf Ladezeit und Seitenrendering
  • Welche Art von "in progress" -Anzeigen zeigt der Browser an (z. B. "Laden" in der Statusleiste, Sanduhr-Mauszeiger).

36
2018-01-12 23:37



Wenn Sie JQuery verwenden, dann stellen Sie das Javascript dort ein, wo Sie es am besten finden und verwenden $(document).ready() um sicherzustellen, dass die Dinge richtig geladen werden, bevor irgendwelche Funktionen ausgeführt werden.

Nebenbei bemerkt: Ich mag alle meine Skript-Tags in der <head> Abschnitt als das scheint der sauberste Ort zu sein.


19
2018-01-12 18:18



XHTML wird nicht validiert, wenn sich das Skript an einer anderen Stelle als im head-Element befindet. Es stellt sich heraus, dass es überall sein kann.

Sie können die Ausführung mit etwas wie jQuery verzögern, so dass es keine Rolle spielt, wo sie platziert wird (außer für einen kleinen Performance-Treffer während des Parsens).


8
2018-01-12 18:22



<script src="myjs.js"></script>
</body>

Script-Tags sollten immer vorher verwendet werden Körper schließen oder Unten in HTML Datei.

Dann können Sie zuerst den Inhalt der Seite sehen, bevor Sie laden js Datei.

Überprüfen Sie dies, wenn erforderlich: http://stevesouders.com/hpws/rule-js-bottom.php


8
2017-07-16 11:16



Die herkömmliche (und weithin akzeptierte) Antwort ist "ganz unten", weil dann das gesamte DOM geladen wurde, bevor etwas ausgeführt werden kann.

Es gibt Dissenters aus verschiedenen Gründen, beginnend mit der verfügbaren Praxis, absichtlich die Ausführung mit einem Seiten-Onload-Ereignis zu beginnen.


5
2018-01-12 18:18



Abhängig vom Skript und seiner Verwendung kann es am besten sein (in Bezug auf Seitenladezeit und Renderzeit), kein konventionelles <script> -Tag als solches zu verwenden, sondern das Laden des Skripts dynamisch asynchron auszulösen.

Es gibt einige verschiedene Techniken, aber am einfachsten ist es, document.createElement ("script") zu verwenden, wenn das window.onload-Ereignis ausgelöst wird. Dann wird das Skript zuerst geladen, wenn die Seite selbst gerendert wurde. Dies hat keinen Einfluss auf die Zeit, die der Benutzer auf das Erscheinen der Seite warten muss.

Dies erfordert natürlich, dass das Skript selbst nicht zum Rendern der Seite benötigt wird.

Weitere Informationen finden Sie im Beitrag Kopplung von asynchronen Skripten von Steve Souders (Schöpfer von YSlow aber jetzt bei Google).


0
2018-01-12 21:06



Das hängt davon ab, ob Sie ein Skript laden, das notwendig ist, um Ihre Seite zu formatieren / Aktionen auf Ihrer Seite auszuführen (wie ein Klick auf eine Schaltfläche). Wenn Ihr Styling 100% CSS ist und Sie alle Fallback-Optionen für die Schaltflächenaktionen haben, können Sie sie unten platzieren.

Oder das Beste (wenn das kein Problem ist) ist, dass Sie eine modale Ladebox erstellen können, platzieren Sie Ihr Javascript unten auf Ihrer Seite und lassen Sie es verschwinden, wenn die letzte Zeile Ihres Skripts geladen wird. Auf diese Weise können Sie verhindern, dass Benutzer Aktionen auf Ihrer Seite ausführen, bevor die Skripts geladen werden. Und vermeiden Sie auch das falsche Styling.


0
2017-11-18 04:41