Die Leistung von JavaScript im Browser kann als das wichtigste Usability-Problem sein, mit dem Front-End-Entwickler konfrontiert sind.
Unter Yahoos Yslow23 -Regeln besteht einer von ihnen darin, JS nach unten zu setzen. Der Grund dafür ist, dass die meisten Browser tatsächlich einen einzelnen Prozess verwenden, um mehrere Aufgaben wie UI zu verarbeiten und JavaScript -Ausführungen zu aktualisieren, und gleichzeitig wird nur eine Aufgabe ausgeführt. Wie lange dauert JavaScript?
Aus grundlegender Perspektive bedeutet dies, dass das Erscheinungsbild des <script> -Tages die gesamte Seite wartet, weil das Skript analysiert und ausgeführt wird. Unabhängig davon, ob der tatsächliche JavaScript -Code in einer irrelevanten externen Datei eingefügt oder enthalten ist, muss der Download- und Parsenprozess der Seite gestoppt werden und warten, bis das Skript diese Verarbeitung abgeschlossen hat, bevor sie fortgesetzt werden. Dies ist ein wesentlicher Bestandteil des Seitenlebenszyklus, da das Skript den Seiteninhalt während der Laufzeit ändern kann. Ein typisches Beispiel ist die Funktion des Dokuments.Write (), zum Beispiel:
Die Codekopie lautet wie folgt:
<html>
<kopf>
<title> Skript Beispiel </title>
</head>
<body>
<p>
<script type = "text/javaScript">
document.write ("Das Datum ist" + (neues Datum ()). Todatestring ());
</script>
</p>
</body>
</html>
Wenn der Browser wie auf der HTML -Seite oben auf ein <script> -Tag trifft, ist es unmöglich vorherzusagen, ob JavaScript dem <p> -Tag Inhalt hinzufügt. Daher stoppt der Browser, führt diesen JavaScript -Code aus und analysiert und übersetzt dann die Seite. Das gleiche passiert beim Laden von JavaScript mithilfe der SRC -Eigenschaft. Der Browser muss zuerst den Code für die externe Datei herunterladen, die einige Zeit dauert, und dann diesen Code analysieren und ausführen. Während dieses Vorgangs sind die Seitenvorsorge und die Benutzerinteraktion vollständig blockiert.
Da das Skript den Download -Prozess anderer Seitenressourcen blockiert, lautet die empfohlene Methode: Alle <Script> -Tags so nahe am Ende des <body> -Tages platzieren, um die Auswirkungen auf den gesamten Seiten -Download zu minimieren. Zum Beispiel:
Die Codekopie lautet wie folgt:
<html>
<kopf>
<title> Skript Beispiel </title>
<link rel = "stylesheet" type = "text/css" href = "styles.css">
</head>
<body>
<p> Hallo Welt! </p>
<-Beispiel für die empfohlene Skriptpositionierung->
<script type = "text/javaScript" src = "file1.js"> </script>
<script type = "text/javaScript" src = "file2.js"> </script>
<script type = "text/javaScript" src = "file3.js"> </script>
</body>
</html>
Dieser Code zeigt an, wo sich das empfohlene <Script> -Tag in der HTML -Datei befindet. Obwohl Skript -Downloads untereinander blockiert sind, wurde die Seite vor dem Benutzer heruntergeladen und angezeigt, und die Geschwindigkeit des Eingebens der Seite wird nicht zu langsam erscheint. Dies ist oben erwähnt, um JS auf den Boden zu bringen.
Außerdem Yahoo! Erstellt ein "föderales Handle" für seine "Yahoo! User Interface, Yui" -Bibliothek, die über ihr "Inhaltsdeliefernetzwerk) implementiert wird. Jede Website kann eine" Bundeshandle "-R -URL verwenden, um anzugeben, welche Dateien im YUI -Dateipaket enthalten sind. Beispielsweise enthält die folgende URL zwei Dateien:
Die Codekopie lautet wie folgt:
<script type = "text/javaScript" src = "http://yui.yahooapis.com/combo?2.7.0/build/yahoo/yahoo-min.js&2.7.0/build/event/event-min.js"> </script>
Diese URL nennt die Yahoo-Min.js- und Event-Min.js-Dateien in Version 2.7.0. Diese Dateien sind zwei separate Dateien auf dem Server, aber wenn der Server diese URL -Anforderung empfängt, werden die beiden Dateien zusammengeführt und an den Client zurückgegeben. Auf diese Weise werden zwei <Script> -Tags nicht mehr benötigt (eine Datei wird für jedes Tag geladen), und ein <skript> -Tag kann sie laden. Dies ist der beste Weg, um mehrere externe JavaScript in HTML -Seiten aufzunehmen.
NoBlocking -Skripte
Das obige ist der beste Weg, um mehrere JavaScript -Skripte in den Anfangszustand der Seite zu laden. JavaScript blockiert dazu, bestimmte Browserverarbeitungsprozesse wie HTTP -Anforderungen und Interface -Aktualisierungen zu blockieren, was die wichtigsten Leistungsprobleme für Entwickler sind. JavaScript -Dateien kurz zu halten und die Anzahl der HTTP -Anforderungen zu begrenzen, ist nur der erste Schritt, um eine reaktionsschnelle Webanwendung zu erstellen.
Aber wie große Webseiten mit viel JS -Code ist es nicht immer die beste Wahl, den Quellcode kurz zu halten. Nicht blockierende Skripte entstanden, was wir brauchen, ist, JavaScript nach und nach der Seite nach und nach hinzuzufügen, was den Browser nicht in gewissem Maße blockiert.
Der Schlüssel zum Blockieren von Skripten besteht darin, den JavaScript -Quellcode nach dem Laden der Seite zu laden, was bedeutet, dass der Code -Download nach dem Ladeereignis des Fensters beginnt.
Verwandte Erklärungen:
Das Ladeereignis des Fensters wird nur einmal und nur einmal nach dem Laden der Seite abgefeuert.
window.onload = function () {} muss warten, bis alle Inhalte auf der Webseite geladen werden (einschließlich aller zugehörigen Elementdateien, wie z. B. Bilder), dh JavaScript kann zu diesem Zeitpunkt auf jedes Element auf der Seite zugreifen.
Die folgenden Methoden sind:
Aufgeschobene Skripte aufgeschobene Skripte
HTML4 definiert ein erweitertes Attribut für das <Script> Tag: Defer.
Dieses Defer -Attribut zeigt an, dass das im Element enthaltene Skript nicht beabsichtigt, die DOM zu ändern, sodass der Code später ausgeführt werden kann. Das Defer-Attribut wird nur von Internet Explorer 4+ und Firefox 3.5+ unterstützt und ist keine ideale Cross-Browser-Lösung. Bei anderen Browsern wird das Aufschubattribut ignoriert. Daher wird das <Script> -Tag auf normale Standardweise verarbeitet, was bedeutet, dass es eine Blockierung verursacht. Wenn dies von verschiedenen Mainstream -Browsern unterstützt wird, ist dies immer noch eine effektive Lösung.
Die Codekopie lautet wie folgt:
<script type = "text/javaScript" src = "file1.js" Defer> </script>
Ein <Script> -Tag mit dem Defer -Attribut kann überall im Dokument platziert werden und startet den Download, wenn es analysiert wird, bis der DOM lädt (bevor der Onload -Ereignisgriff aufgerufen wird). Wenn eine Defer -JavaScript -Datei heruntergeladen wird, blockiert sie keine anderen Verarbeitungsprozesse im Browser, sodass diese Dateien parallel zu anderen Ressourcen heruntergeladen werden können.
Sie können den folgenden Code verwenden, um zu testen, ob der Browser das Defer -Attribut unterstützt:
Die Codekopie lautet wie folgt:
<html>
<kopf>
<title> script Defer Beispiel </title>
</head>
<body>
<Script Defer> alert ("Defer"); </script>
<Script> alert ("Skript"); </script>
<Script> window.onload = function () {alert ("laden");}; </script>
</body>
</html>
Wenn der Browser auf Verschiebung nicht unterstützt, lautet die Reihenfolge der Popup-Dialogfelder "Verschiebung", "Skript" und "Laden".
Wenn der Browser auf Verschiebung unterstützt wird, ist die Reihenfolge der Popup-Dialogfelder "Skript", "Load", "Defer".
Dynamische Skriptelemente
DOM ermöglicht es uns, fast alle Dokumentinhalte von HTML mit JavaScript dynamisch zu erstellen, und ein neues <skript> -Element kann sehr einfach über Standard DOM erstellt werden:
Die Codekopie lautet wie folgt:
1 var script = document.createelement ("script");
2 script.type = "text/javaScript";
3 script.src = "file1.js";
4 document.body.AppendChild (Skript);
Das neue <Script> -Element lädt die Quelldatei von Datei1.js. Laden Sie diese Datei sofort herunter, nachdem das Element zur Seite hinzugefügt wurde. Der wichtigste Punkt dieser Technologie ist, dass unabhängig davon, wo der Download gestartet wird, der Download und Ausführen der Datei keine andere Seitenverarbeitung blockiert.
Wenn eine Datei mit einem dynamischen Skriptknoten heruntergeladen wird, wird der zurückgegebene Code normalerweise sofort ausgeführt (außer Firefox und Opera, wodurch alle vorherigen dynamischen Skriptknoten ausgeführt werden).
In den meisten Fällen hoffen wir, eine Funktion zur Implementierung des dynamischen Downloads von JavaScript -Dateien aufzurufen. Die folgende Funktionskapselung implementiert Standard -Implementierungen und IE -Implementierungen:
Die Codekopie lautet wie folgt:
Funktion loadscript (URL, Rückruf) {
var script = document.createelement ("script");
script.type = "text/javaScript";
if (script.readystate) {// dh
script.onReadyStatechange = function () {
if (script.readystate == "geladen" || script.readystate == "complete") {
script.onReadyStatechange = null;
callback ();
}
};
}
sonst {// andere
script.onload = function () {callback ();
};
}
script.src = url;
document.getElementsByTagName ("head") [0] .AppendChild (Skript);
}
ladeScript ("file1.js", function () {// call
alert ("Datei wird geladen!");
});
Diese Funktion akzeptiert zwei Parameter: die URL der JavaScript -Datei und eine Rückruffunktion, die ausgelöst wird, wenn der JavaScript -Empfang abgeschlossen ist. Die Attributprüfung wird verwendet, um zu bestimmen, welches Ereignis zu überwachen ist. Der letzte Schritt ist das SRC -Attribut und füge die JavaScript -Datei zum Kopf hinzu.
Dynamisches Skriptladen ist das am häufigsten verwendete Muster in nicht blockierenden JavaScript-Downloads, da es Kreuzbrowser sein kann und einfach zu bedienen ist.
Xmlhttprequest Skript Injektion XHR -Skriptinjektion
Eine andere Möglichkeit, Skripte auf nicht blockierende Weise zu erhalten, besteht darin, Skripte in die Seite mit dem XMLHTTPREquest (XHR) -Objekt (XHR) zu injizieren. Diese Technik erstellt zuerst ein XHR -Objekt, lädt dann eine JavaScript -Datei herunter und injiziert dann JavaScript -Code mit einem dynamischen <skript> -Element in die Seite. Schauen Sie sich die Demo an:
Die Codekopie lautet wie folgt:
var xhr = new xmlhttprequest ();
xhr.open ("get", "file1.js", true);
xhr.onreadyStatechange = function () {
if (xhr.readystate == 4) {
if (xhr.status> = 200 && xhr.status <300 || xhr.status == 304) {// Überprüfen Sie den HTTP -Statuscode
var script = document.createelement ("script");
script.type = "text/javaScript";
script.text = xhr.responsetext;
document.body.appendchild (script);
}
}
};
xhr.send (null);
Dieser Code sendet eine Datei -GET -Anforderung an den Server, um Datei1.js abzurufen. Der Event -Handler von OnReadyStatEchange prüft, ob ReadyState 4 ist, und prüft dann, ob der HTTP -Statuscode gültig ist (200 bedeutet, dass die Clientanforderung erfolgreich war, 2xx eine gültige Antwort und 304 bedeutet eine zwischengespeicherte Antwort). Wenn eine gültige Antwort empfangen wird, wird ein neues <Script> -Element erstellt und sein Textattribut auf die vom Server empfangene Antwort auf die Antwort der Antwort festgelegt. Dies erstellt tatsächlich ein <Script> -Element mit Inline -Code, und sobald ein neues <script> -Element zum Dokument hinzugefügt wird, wird der Code ausgeführt und zur Verwendung bereit.
Der Vorteil dieser Methode besteht darin, dass sie eine gute Kompatibilität hat und Sie JavaScript -Code herunterladen können, der nicht sofort ausgeführt wird. Da der Code außerhalb des <Script> -Tags zurückgibt, wird er nach dem Herunterladen nicht automatisch ausgeführt, sodass Sie die Ausführung verschieben können.
Die Bestimmung dieser Methode unterliegt den homologen Browser -Beschränkungen. JavaScript -Dateien müssen in derselben Domäne wie der Seite platziert werden und können nicht aus dem CDN (Inhaltszustellungsnetzwerk) heruntergeladen werden. Aus diesem Grund verwenden große Webseiten normalerweise keine XHR -Skript -Injektionstechnologie.
Empfohlenes Schiebermuster empfohlenes Schiebermuster
Die empfohlene Methode zum Laden einer großen Menge JavaScript auf eine Seite ist in zwei Schritte unterteilt:
Der erste Schritt enthält den Code, der zum dynamischen Laden von JavaScript erforderlich ist, und dann den Teil mit Ausnahme von JavaScript, die für die Seiteninitialisierung erforderlich sind. Dieser Teil des Codes ist so klein wie möglich und kann nur die Funktion loadscript () enthalten. Es lädt und läuft sehr schnell herunter und verursacht nicht viel Eingriff in die Seite.
Der zweite Schritt besteht darin, den Rest von JavaScript zu laden, nachdem der erste Code fertig ist.
Zum Beispiel:
Die Codekopie lautet wie folgt:
1 <skript type = "text/javaScript" src = "lader.js">
2 </script> <script type = "text/javaScript">
3 Loadscript ("the-rest.js", function () {
4 application.init ();
5});
6
7 </script>
Platzieren Sie diesen Code vor dem engen Tag </body> des Körpers. Der Vorteil davon ist, dass dies zunächst sicherstellt, dass JavaScript ausgeführt wird, ohne andere Teile anderer Seiten anzuzeigen. Zweitens, wenn der zweite Teil der JavaScript -Datei heruntergeladen wird, wurden alle erforderlichen DOMs für die Anwendung erstellt und bereit, aufgerufen zu werden, und vermeiden Sie die Verwendung zusätzlicher Ereignisverarbeitung (z. B. Fenster.onload), um zu wissen, ob die Seite fertig ist.
Eine andere Option besteht darin, die Funktion loadscript () direkt in die Seite einzubetten, wodurch der Overhead einer HTTP -Anforderung reduziert werden kann. Zum Beispiel:
Die Codekopie lautet wie folgt:
1 <Skript type = "text/javaScript">
Funktion loadscript (URL, Rückruf) {
var script = document.createelement ("script");
script.type = "text/javaScript";
if (script.ReadyState) {// IE script.onreadyStatechange = function () {
if (script.readystate == "geladen" || script.readystate == "complete") {
script.onReadyStatechange = null;
callback ();
}
};
} else {// andere
script.onload = function () {
callback ();
};
}
script.src = url;
document.getElementsByTagName ("head") [0] .AppendChild (Skript);
}
loadscript ("the-rest.js", function () {
Application.init ();
});
</script>
Sobald der Seiteninitialisierungscode heruntergeladen wurde, können Sie auch die Funktion ladeScript () verwenden, um die zusätzlichen funktionalen Funktionen zu laden, die von der Seite erforderlich sind.
Einführung eines gemeinsamen Werkzeugs, Ryan Grove von Yahoo! Durchsuchen Sie die LAYLOAD -Bibliothek (siehe: http://github.com/rgrove/lazyload/). Lazyload ist eine leistungsstarke loadscript () -Funktion. Lazyload hat nur etwa 1,5 KB nach der Skalierung. Beispiele für die Nutzung sind wie folgt:
Die Codekopie lautet wie folgt:
<script type = "text/javaScript" src = "Lazyload-min.js"> </script>
<script type = "text/javaScript">
Lazyload.js ("the-rest.js", function () {
Application.init ();
});
</script>
Zusammenfassung
1. Platzieren Sie alle <Script> -Tags unten auf der Seite nahe am Schluss -Tag </body>. Diese Methode stellt sicher, dass die Seite vor dem Ausführen des Skripts analysiert wird.
2. Packen Sie die Skripte in Gruppen. Je weniger <Script> Tags auf einer Seite, desto schneller wird die Seite schneller geladen und reagiert. Dies gilt sowohl für externe Skriptdateien als auch für Inline -Code.
3. Es gibt verschiedene Möglichkeiten, JavaScript mit nicht blockierenden Methoden herunterzuladen:
1). Fügen Sie dem <Script> Tag ein Defer -Attribut hinzu
2). Erstellen Sie das <Script> -Element dynamisch und verwenden Sie es, um den Code herunterzuladen und auszuführen
3). Verwenden Sie das XHR -Objekt, um den Code herunterzuladen und ihn in die Seite zu injizieren
Durch die obige Strategie kann die tatsächliche Leistung von Internetnutzern, die Javascript Code verwenden, erheblich verbessert werden.
Nachschlagewerk "High Performance JavaScript".