Frage

Vor kurzem sah ich einige HTML-Seiten mit nur einem einzigen <script> element <head>...

<head>
    <title>Example</title>
    <script src="script.js" type="text/javascript"></script>
    <link href="plain.css" type="text/css" rel="stylesheet" />
</head>

Diese script.js fügt dann alle anderen notwendigen <script> Elemente und <link> Elemente, um das Dokument mit document.write(...):(oder könnte es verwenden document.createElement(...) etc)

document.write("<link href=\"javascript-enabled.css\" type=\"text/css\" rel=\"styleshet\" />");
document.write("<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js\" type=\"text/javascript\"></script>");
document.write("<script src=\"https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.10/jquery-ui.min.js\" type=\"text/javascript\"></script>");
document.write("<link href=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/trontastic/jquery-ui.css\" type=\"text/css\" rel=\"stylesheet\" />")
document.write("<script src=\"validation.js\" type=\"text/css\"></script>")

Beachten Sie, dass es gibt ein plain.css CSS-Datei in das Dokument ein <head> und script.js fügt nur jede und alle CSS und JavaScript, die verwendet werden würde durch ein JS-aktivierten Benutzer-agent.

Was sind einige der vor-und Nachteile dieser Technik?

War es hilfreich?

Lösung

Die Blockier Natur des Dokuments.Write

document.write Pause wird alles, was der Browser auf der Seite arbeitet (einschließlich Parsen). Es wird dringend empfohlen, um vermeiden Wegen dieses Blockierverhaltens. Der Browser hat keine Möglichkeit zu wissen, was Sie zu diesem Zeitpunkt in den HTML -Textstream einlösen, oder ob das Schreiben alles auf dem Dom -Baum völlig ausschüttet, sodass er aufhören muss, bis Sie fertig sind.

Im Wesentlichen zwingt das Laden von Scrips auf diese Weise den Browser, HTML zu stoppen. Wenn Ihr Skript in der Linie ist, führt der Browser diese Skripte auch aus, bevor es weitergeht. Als Seitenstart wird immer empfohlen, dass Sie das Ladekripte bis zum Auf verschieben nach Ihre Seite ist analysiert und Sie haben dem Benutzer eine angemessene Benutzeroberfläche gezeigt.

Wenn Ihre Skripte aus separaten Dateien im Attribut "SRC" geladen werden, werden die Skripte möglicherweise nicht konsistent über alle Browser ausgeführt.

Verlieren von Browsergeschwindigkeitsoptimierungen und Vorhersehbarkeit

Auf diese Weise verlieren Sie viele der Leistungsoptimierungen moderner Browser. Auch wenn Ihre Skripte ausgeführt werden, können möglicherweise unvorhersehbar sein.

Zum Beispiel führen einige Browser die Skripte direkt nach dem Schreiben aus. In solchen Fällen verlieren Sie parallele Downloads von Skripten (da der Browser das zweite Skript -Tag erst beim Herunterladen und Ausführen des ersten angezeigt hat). Sie verlieren parallele Downloads von Skripten, Stylesheets und anderen Ressourcen (viele Browser können gleichzeitig Ressourcen, Stylesheets und Skripte herunterladen).

Einige Browser verschieben die Skripte bis nach dem Ende, um sie auszuführen.

Der Browser kann das HTML nicht weiter analysieren, während document.write stattfindet und in bestimmten Fällen, wenn die geschriebenen Skripte aufgrund des Blockierverhaltens von ausgeführt werden document.write, Also zeigt Ihre Seite viel langsamer.

Mit anderen Worten, Ihre Website ist so langsam geworden, wie sie auf einen jahrzehntelangen Browser ohne Optimierungen geladen wurde.

Warum sollte es so jemand tun?

Der Grund, warum Sie so etwas verwenden möchten, ist normalerweise die Wartbarkeit. Zum Beispiel haben Sie möglicherweise eine riesige Site mit Tausenden von Seiten, die jeweils dieselbe Skripte und Stylesheets laden. Wenn Sie jedoch eine Skriptdatei hinzufügen, möchten Sie nicht Tausende von HTML -Dateien bearbeiten, um die Skript -Tags hinzuzufügen. Dies ist besonders mühsam beim Laden von JavaScript -Bibliotheken (z. B. Dojo oder JQuery) - Sie müssen jede HTML -Seite ändern, wenn Sie auf die nächste Version aktualisieren.

Das Problem ist, dass JavaScript keine @Include- oder @Import -Anweisung für Sie für andere Dateien enthält.

Einige Lösungen

Die Lösung hierfür besteht wahrscheinlich nicht darin, Skripte über injizieren document.write, sondern durch:

  1. Verwenden von @import -Direktiven in Stylesheets
  2. Verwenden einer Server -Skriptsprache (z. B. PHP), um Ihre "Masterseite" zu verwalten und alle anderen Seiten zu generieren (wenn Sie dies jedoch nicht verwenden können und viele HTML -Seiten einzeln beibehalten müssen, ist dies keine Lösung).
  3. Vermeiden document.write, aber laden Sie die JavaScript -Dateien über XHR und bewerten Sie sie - dies kann jedoch Sicherheitsbedenken haben
  4. Verwenden Sie eine JavaScript-Bibliothek (z. B. DOJO) mit Modulladungsfunktionen, damit Sie eine Master-JS-Datei aufbewahren können, die andere Dateien lädt. Sie werden nicht vermeiden, die Versionsnummern der Bibliotheksdatei zu aktualisieren ...

Andere Tipps

Ein großer Nachteil ist die Browser -Inkompatibilität. Nicht alle Browser holen die Ressourcen korrekt ab und integrieren in das DOM. Daher ist es riskant, diesen Ansatz zu verwenden. Dies gilt mehr für Stylesheets als für Skripte.

Ein weiteres Problem ist die Wartbarkeit. Verketten und Schreiben von Zeichenfolgen zum Hinzufügen von DOM -Elementen auf dem Kunden -Side können zu einem Alptraum für Wartung werden. Es ist besser, DOM -Methoden wie CreateLement zu verwenden, um semantisch Elemente zu erstellen.

Ein offensichtlicher Vorteil ist, dass es die bedingte Verwendung von Ressourcen erheblich erleichtert. Sie können eine Logik haben, die feststellt, welche Ressourcen geladen werden sollen, und damit den Bandbreitenverbrauch und die Gesamtverarbeitungszeit für die Seite verringert. Ich würde einen Bibliotheksanruf verwenden, wie z. Der Vorteil ist, dass ein solcher Ansatz sauberer ist und Ihnen auch Code ausführen kann, wenn die Anforderung abgeschlossen ist oder fehlschlägt.

Nun, ich kann meinen Hut genauso gut in den Ring werfen ...

Wenn Sie die Closure Library von Google, Base.js, untersuchen, werden Sie dieses Dokument sehen. writeScriptTag_() Funktion. Dies ist ein wesentlicher Bestandteil des Abhängigkeitsverwaltungssystems, das "Verschluss" bietet und ein enormer Vorteil bei der Erstellung einer komplizierten, multi-file-JavaScript-Anwendung-die Voraussetzungen der Datei/Code ermöglichen die Ladereihenfolge. Wir verwenden derzeit diese Technik und hatten wenig Probleme damit. TBH, wir hatten kein einziges Problem mit der Browserkompatibilität und testen regelmäßig auf IE 6/7/8, FF3/2, Safari 4/5 und Chrome Neueste.

Der einzige Nachteil, den wir bisher hatten, ist, dass es schwierig sein kann, Probleme aufzuspüren, die durch das zweimalige Laden einer Ressource verursacht werden oder überhaupt nicht geladen werden. Da der Akt der Laderessourcen programmatisch ist, unterliegt sie programmatischen Fehlern. Im Gegensatz zum Hinzufügen der Tags direkt zum HTML kann es schwierig sein, zu erkennen, wie genau die Ladereihenfolge ist. Dieses Problem kann jedoch weitgehend überwunden werden, indem eine Bibliothek mit irgendeiner Form von Abhängigkeitsmanagementsystem wie Verschluss oder Dojo verwendet wird.

BEARBEITEN: Ich habe ein paar Kommentare zu dieser Natur abgegeben, aber ich fand es am besten, in meiner Antwort zusammenzufassen: Es gibt einige Probleme mit dojo.require () und jQuery.getScript () (beide, die eine AJAX -Anfrage und Evaly ultima durchführen).

  1. Wenn Sie über AJAX geladen werden, bedeutet dies kein Kreuzkripte - dh kein Lade -JavaScript, das nicht von Ihrer Website stammt. Dies ist ein Problem, wenn Sie einbeziehen möchten https://ajax.googleapis.com wie in der Beschreibung aufgeführt.
  2. Eval'd -Skripte werden in der Liste der Seitenskripte von JavaScript Debugger nicht angezeigt, was das Debugging sehr herausfordernd macht. Jüngste Veröffentlichungen von Firebug zeigen Ihnen den Bewertungscode. Dateinamen gehen jedoch verloren, indem Sie die Bruchpunkte mühsam einstellen. Afaik, Webkit Javascript -Konsole und IE8 -Entwicklertools unterlassen Sie Eval'd Skripte anzeigen.

Es hat den Vorteil, dass Sie die Skriptreferenzen in jeder HTML -Datei nicht wiederholen müssen. Der Nachteil ist, dass der Browser muss Abrufen und führen Sie die Haupt -JavaScript -Datei aus, bevor sie die anderen geladen werden können.

Ich denke, ein Vorteil, den ich mir vorstellen könnte, wäre, wenn Sie diese Skripte auf mehreren Seiten verwenden. Sie müssen nur daran denken, ein Skript einzuschließen, und es speichert einen Platz.

Bei Google PageSpeed, Sie sind stark raten Ihnen von der Verwendung dieser Technik, denn es macht die Dinge langsamer.Neben dem sequentiellen laden von Ihrem script.js bevor all die anderen, es gibt einen anderen Haken:

Moderne Browser verwenden das spekulative Parsen, um effizienter zu entdecken externen Ressourcen [...] Somit ist die Verwendung von JavaScript-Dokument.write() zum abrufen von externen Ressourcen, die es unmöglich macht, für den spekulativen parser zu entdecken, die Ressourcen, die können Verzögerung die herunterladen, das Parsen und Rendern von Ressourcen.

Es ist auch möglich, dass dies von einem SEO-Unternehmen als Empfehlung geschrieben wurde, um das Kopfelement nach Möglichkeit kürzer zu machen. Daher liegt eindeutiger Inhalt näher am oberen Rand des Dokuments und erstellt auch ein höheres Text-zu-HTML-Verhältnis. Obwohl es sich anhört, ist alles in allem, wie keine sehr gute Möglichkeit, dies zu tun. Obwohl es die Wartung zeitaufwändiger machen würde, wäre ein besserer Ansatz wahrscheinlich, JavaScript in eine einzelne .js-Datei und CSS in eine einzelne .css-Datei zu verdichten, wenn sie als äußerst notwendig galt, um die Größe der Kopfelemente zu reduzieren.

Ein großer Nachteil ist das Hinzufügen scripts in den Kopf wird die Verarbeitung des Dokuments pausieren, bis diese Skripte vollständig analysiert und ausgeführt wurden (weil der Browser glaubt, sie könnten verwenden document.write). - Dies wird die Reaktionsfähigkeit beeinträchtigen.

Tagen werden empfohlen, dass Sie Ihre Skript -Tags richtig einstellen </body>. Natürlich ist dies nicht 100% möglich, aber wenn Sie verwenden Unobrusve JavaScript (Wie Sie sollten), können alle Skripte am Ende des Dokuments respektiert werden.

HTML5 kam mit dem async Attribut, das den Browser nur vorschlägt, um die Skripte nach dem Laden des Hauptdokuments auszuführen. Dies ist das Verhalten von Skript-inerierten Skripten in vielen Browsern, aber nichts von ihnen.

ich rate gegen Verwendung document.write um jeden Preis. Auch ohne dies führt dies zu einer zusätzlichen Anfrage zum Server. (Wir möchten die Anzahl der Anfragen beispielsweise mit inimieren CSS Sprites.)

Und ja, wie andere bereits erwähnt, wird Ihre Seite ohne CSS (was es potenziell unbrauchbar macht), wenn das Skripten deaktiviert ist).

  1. Wenn JavaScript ist deaktiviert - <script> and <link> Elemente werden überhaupt nicht hinzugefügt.

  2. Wenn Sie JavaScript -Init -Funktionen am Ende Ihrer Seite (was eine gute Praxis ist) platzieren und CSS mit JavaScript verknüpfen, kann dies zu einer gewissen Verzögerung vor dem Lasten von CSS führen (kaputte Layout ist für kurze Zeit sichtbar).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top