web-dev-qa-db-de.com

Wann sollte ich Inline vs. externes Javascript verwenden?

Ich würde gerne wissen, wann ich externe Skripts einbinden oder in HTML-Code schreiben sollte, was die Leistung und Wartungsfreundlichkeit anbelangt.

Was ist die allgemeine Praxis dafür?

Real-World-Szenario - Ich habe mehrere HTML-Seiten, die eine clientseitige Formularprüfung erfordern. Dafür verwende ich ein jQuery-Plugin, das ich auf allen diesen Seiten einbinde. Aber die Frage ist:

  • schreiben Sie die Codebits, die dieses Skript inline konfigurieren.
  • alle Bits in einer Datei enthalten, die alle HTML-Seiten gemeinsam nutzen?
  • jedes Bit in einer separaten externen Datei einschließen, eines für jede HTML-Seite?

Vielen Dank.

121
Dan Burzo

Als diese Antwort ursprünglich veröffentlicht wurde (2008), war die Regel einfach: Alle Skripts sollten extern sein. Sowohl für die Wartung als auch für die Leistung.

(Warum Leistung? Denn wenn der Code separat ist, kann er einfacher von Browsern zwischengespeichert werden.)

JavaScript gehört nicht zum HTML-Code und wenn es Sonderzeichen enthält (z. B. <, >), entstehen sogar Probleme.

Heutzutage hat sich die Skalierbarkeit im Web geändert. Das Reduzieren der Anzahl von Anforderungen ist aufgrund der Latenzzeit bei der Erstellung mehrerer HTTP-Anforderungen zu einer gültigen Überlegung geworden. Dies macht die Antwort komplexer: In den meisten Fällen wird die Verwendung von JavaScript mit still empfohlen. In bestimmten Fällen, insbesondere bei sehr kleinen Codeteilen, ist es jedoch sinnvoll, sie in den HTML-Code der Website zu integrieren.

108
Konrad Rudolph

Wartungsfreundlichkeit ist definitiv ein Grund, sie extern zu halten, aber wenn die Konfiguration ein Einzeiler ist (oder im Allgemeinen kürzer als der HTTP-Overhead, den Sie für das externe Erstellen dieser Dateien erhalten würden), ist es aus Performance-Gründen besser, sie inline zu halten. Denken Sie immer daran, dass jede HTTP-Anforderung in Bezug auf die Ausführungszeit und den Datenverkehr etwas Mehraufwand verursacht. 

Natürlich ist dies alles irrelevant, wenn Ihr Code länger als ein paar Zeilen ist und nicht wirklich für eine einzelne Seite gilt. In dem Moment, in dem Sie den Code wiederverwenden möchten, machen Sie ihn extern. Wenn nicht, schauen Sie sich die Größe an und entscheiden Sie dann.

31
Horst Gutmann

Das Externalisieren von Javascript ist eine der Yahoo-Leistungsregeln: http://developer.yahoo.com/performance/rules.html#external

In der Regel ist es eine gute Sache, dass Sie die Skripts immer externalisieren sollten. In einigen Fällen möchten Sie vielleicht einige der Skripts und Stile integrieren. Sie sollten jedoch nur Dinge integrieren, von denen Sie wissen, dass sie die Leistung verbessern (weil Sie dies gemessen haben).

21
Joeri Sebrechts

Wenn Sie nur auf die Leistung Wert legen, sind die meisten Ratschläge in diesem Thread völlig falsch und werden in der SPA-Ära immer mehr falsch. Wir können davon ausgehen, dass die Seite ohne den JS-Code unbrauchbar ist. Ich habe unzählige Stunden damit verbracht, die Ladezeiten von SPA-Seiten zu optimieren und diese Ergebnisse mit verschiedenen Browsern zu überprüfen. Auf der ganzen Linie kann die Leistungssteigerung durch Neu-Orchestrierung Ihrer HTML-Datei sehr dramatisch sein.

Um die beste Leistung zu erzielen, müssen Sie sich Seiten als zweistufige Raketen vorstellen. Diese beiden Stufen entsprechen grob den <head>- und <body>-Phasen, denken aber stattdessen als <static> und <dynamic>. Der statische Teil ist im Grunde eine String-Konstante, die Sie so schnell wie möglich in die Antwortleitung verschieben können. Dies kann ein wenig schwierig sein, wenn Sie eine Menge Middleware verwenden, die Cookies setzt (diese müssen vor dem Senden von http-Inhalten gesetzt werden), aber im Prinzip wird nur der Antwortpuffer geleert. etc) auf dem Server. Das hört sich vielleicht schwierig an, aber dann erkläre ich es nur falsch, weil es fast trivial ist. Wie Sie vielleicht schon erraten haben, sollte dieser statische Teil alle Javascript enthalten, die inline dargestellt und minimiert sind. Es würde ungefähr so ​​aussehen

<!DOCTYPE html>
     <html>
         <head>
             <script>/*...inlined jquery, angular, your code*/</script>
             <style>/* ditto css */</style>
         </head>
         <body>
             <!-- inline all your templates, if applicable -->
             <script type='template-mime' id='1'></script>
             <script type='template-mime' id='2'></script>
             <script type='template-mime' id='3'></script>

Da es Ihnen fast nichts kostet, diesen Teil über die Leitung zu senden, können Sie davon ausgehen, dass der Client diese Verbindung mit einer Latenz von etwa 5 ms + nach dem Herstellen der Verbindung zu Ihrem Server empfängt. Angenommen, der Server ist nahe genug, kann diese Latenz zwischen 20 ms und 60 ms liegen. Browser beginnen mit der Verarbeitung dieses Abschnitts, sobald sie ihn erhalten, und die Verarbeitungszeit dominiert normalerweise die Übertragungszeit um den Faktor 20 oder mehr. Dies ist jetzt Ihr amortisiertes Fenster für die serverseitige Verarbeitung des <dynamic>-Abschnitts.

Es dauert etwa 50 ms, bis der Browser (Chrome, Rest um 20% langsamer) Inline-Jquery + -Signal + Winkel + Ng-Animation + Ng-Touch + NG-Routen + Lodge + verarbeitet. Das ist schon erstaunlich an und für sich. Die meisten Web-Apps verfügen über weniger Code als all diese populären Bibliotheken, aber lassen Sie uns sagen, Sie haben genauso viel, also würden wir Latenzzeit + 100 ms für die Verarbeitung auf dem Client gewinnen (dieser Latenzgewinn kommt vom zweiten Übertragungsblock). Zum Zeitpunkt des Eintreffens des zweiten Chunks haben wir den gesamten js-Code und alle Templates verarbeitet, und wir können mit der Ausführung von dom-Transformationen beginnen.

Sie können einwenden, dass diese Methode orthogonal zum Inlining-Konzept ist, dies ist jedoch nicht der Fall. Wenn Sie anstelle von Inlining eine Verknüpfung zu CDNs oder Ihren eigenen Servern herstellen, muss der Browser eine oder mehrere andere Verbindungen öffnen und die Ausführung verzögern. Da diese Ausführung grundsätzlich kostenlos ist (da der Server mit der Datenbank spricht), muss klar sein, dass alle diese Sprünge mehr kosten würden, als überhaupt keine Sprünge zu machen. Wenn es einen Browser gibt, der besagt, dass externe js schneller ausgeführt werden, könnten wir messen, welcher Faktor dominiert. Meine Messungen zeigen, dass zusätzliche Anforderungen in diesem Stadium die Leistung beeinträchtigen. 

Ich arbeite viel mit der Optimierung von SPA-Apps. Es ist üblich, dass die Leute denken, dass das Datenvolumen eine große Sache ist, während die Wahrheitslatenz und die Ausführung oft dominieren. Die abgebildeten Minibibliotheken summieren sich auf bis zu 300 KByte Daten, und das sind nur 68 KByte komprimierte Dateien oder 200 ms Download auf einem 3-MBit-3Git/4g-Telefon. Dies ist genau die Latenz, die das gleiche Telefon benötigt, um zu überprüfen, ob es die gleichen Daten hat bereits in seinem Cache, auch wenn es sich um einen Proxy-Cache handelt, da die mobile Latenzsteuer (Phone-to-Tower-Latenz) immer noch gilt. In der Zwischenzeit haben Desktop-Verbindungen, die eine niedrigere First-Hop-Latenz aufweisen, ohnehin eine höhere Bandbreite. 

Kurz gesagt, jetzt (2014) ist es am besten, alle Skripts, Stile und Vorlagen zu integrieren. 

EDIT (MAI 2016)

Da JS-Anwendungen weiter wachsen und einige meiner Nutzlasten jetzt bis zu 3 Megabyte an reduziertem Code stapeln, wird es offensichtlich, dass zumindest gängige Bibliotheken nicht mehr inline sein sollten.

19
Gleno

ich denke, das spezifisch für eine Seite, kurzer Skriptfall ist (nur) ein vertretbarer Fall für ein Inline-Skript

14
Gene T

Eigentlich gibt es einen ziemlich soliden Fall für Inline-Javascript. Wenn die js klein genug ist (Einzeiler), neige ich dazu, die Javascript-Inline aus zwei Gründen zu bevorzugen:

  • Lokalität. Es ist nicht notwendig, in einer externen Datei zu navigieren, um das Verhalten einiger Javascript zu überprüfen
  • AJAX. Wenn Sie einen Teil der Seite über AJAX aktualisieren, verlieren Sie möglicherweise alle DOM-Handler (Onclick usw.) für diesen Abschnitt, je nachdem, wie Sie sie gebunden haben. Mit jQuery können Sie beispielsweise die Methoden live oder delegate verwenden, um dies zu umgehen, aber ich finde, wenn js klein genug ist, empfiehlt es sich, es einfach inline zu setzen. 
9
Miguel Ping

Ein weiterer Grund, warum Sie immer externe Skripts verwenden sollten, ist der einfachere Übergang zu Content Security Policy (CSP) . Die CSP-Standardeinstellungen verbieten alle Inline-Skripts, wodurch Ihre Site widerstandsfähiger gegen XSS-Angriffe wird.

5
chiborg

Ich würde mir den erforderlichen Code ansehen und ihn in beliebig viele Dateien aufteilen. Jede js-Datei würde nur eine "logische Menge" von Funktionen usw. enthalten, z. eine Datei für alle Login-Funktionen.

Bei der Site-Entwicklung auf jeder HTML-Seite beziehen Sie dann nur die erforderlichen Elemente ein. Wenn Sie mit Ihrer Site online gehen, können Sie die Optimierung optimieren, indem Sie jede js-Datei, die eine Seite benötigt, in einer Datei zusammenfassen.

4
Gene

Die einzige Verteidigung, die ich für Inline-Javascript anbieten kann, ist, dass bei Verwendung von stark typisierten Ansichten mit .net MVC auf c # -Variablen mit mittlerem Javascript verwiesen werden kann, was ich als nützlich erachtet habe.

4
Austin_G

Drei Überlegungen:

  • Wie viel Code benötigen Sie (manchmal sind Bibliotheken ein erstklassiger Konsument)?
  • Besonderheit: Funktioniert dieser Code nur im Zusammenhang mit diesem bestimmten Dokument oder Element?
  • Jeder Code im Dokument macht ihn länger und damit langsamer. Außerdem machen SEO-Überlegungen deutlich, dass Sie das interne Scripting minimieren ...
3
roenving

Um JavaScript extern zu halten:

In ASP.NET 3.5SP1 wurde kürzlich die Funktionalität zum Erstellen einer Composite-Skriptressource (Zusammenführen einer Reihe von JS-Dateien in eine) eingeführt. Ein weiterer Vorteil ist, wenn die Webserver-Komprimierung aktiviert ist. Das Herunterladen einer etwas größeren Datei hat eine bessere Kompressionsrate als viele kleinere Dateien (auch weniger http-Overhead, Roundtrip usw.). Ich denke, das erspart das anfängliche Laden der Seite, und das Browser-Caching tritt wie oben erwähnt ein.

Abgesehen von ASP.NET werden in diesem Screencast die Vorteile ausführlicher erläutert: http://www.asp.net/learn/3.5-SP1/video-296.aspx

2
Brendan Kowitz

Ein weiterer versteckter Vorteil von externen Skripts ist, dass Sie sie leicht über einen Syntax-Checker wie jslint ausführen können. Das kann Sie vor vielen herzzerreißenden, schwer zu findenden IE6-Fehlern bewahren.

2
Ken

Externe Skripts lassen sich auch leichter mit Firebug debuggen. Ich mag es, mein JavaScript zu testen und alle externen Hilfen zu haben. Ich hasse es, JavaScript in PHP Code und HTML zu sehen, es sieht für mich wie ein großes Chaos aus.

2
Clutch

Google hat Ladezeiten in das Seitenranking aufgenommen. Wenn Sie viel Inline eingeben, dauert es länger, bis die Spinnen Ihre Seite durchlaufen. In jedem Fall können unterschiedliche Strategien Einfluss auf Ihr Ranking haben.

1
Kees Hessels

In Ihrem Szenario klingt es so, als würde das Schreiben der externen Dateien in eine von den Seiten gemeinsam genutzte Datei für Sie gut sein. Ich stimme mit dem oben Gesagten überein.

1
mattlant

Behalten Sie Ihren Code während des frühen Prototypens inline, um eine schnelle Iteration zu gewährleisten. Stellen Sie jedoch sicher, dass der Code bis zum Produktionszeitpunkt extern ist.

Ich wage sogar zu sagen, dass, wenn Sie Ihr Javascript nicht extern platzieren können, ein schlechtes Design unter Ihren Händen ist und Sie Ihre Daten und Skripts umgestalten sollten

1
Robert Gould

ich denke, Sie sollten Inline bei der Erstellung von Websites mit einer Seite verwenden, da Skripts nicht auf mehreren Seiten gemeinsam genutzt werden müssen

1
Zak Sheikh

Versuchen Sie immer, externe Js zu verwenden, da Inline-Js immer schwierig zu warten sind. 

Darüber hinaus ist es professionell erforderlich, dass Sie eine externe js verwenden, da die Mehrheit der Entwickler die externe Verwendung von js empfiehlt.

Ich selbst benutze externe Js.

0
user9687054