web-dev-qa-db-ger.com

Analysieren Browser Javascript bei jedem Seitenaufruf?

Analysieren Browser (IE und Firefox) bei jeder Aktualisierung der Seite verknüpfte Javascript-Dateien?

Sie können die Dateien zwischenspeichern, also werden sie wahrscheinlich nicht jedes Mal versuchen, sie herunterzuladen, aber da jede Seite im Grunde genommen separat ist, erwarte ich, dass sie alten Code entfernen und neu analysieren.

Dies ist ineffizient, obwohl es vollkommen verständlich ist, aber ich frage mich, ob moderne Browser clever genug sind, um den Parsing-Schritt innerhalb von Websites zu vermeiden. Ich denke an Fälle, in denen eine Site eine Javascript-Bibliothek verwendet, wie ExtJS oder jQuery usw.

185
Steve Jones

Dies sind die Details, die ich ausgraben konnte. Zunächst ist anzumerken, dass JavaScript zwar normalerweise als interpretiert und auf einer VM ausgeführt betrachtet wird, dies jedoch bei den modernen Interpretern nicht der Fall ist, die dazu neigen, die Quelle direkt in Maschinencode zu kompilieren (mit Ausnahme des IE).


Chrome: V8 Engine

V8 hat einen Kompilierungscache. Hier wird kompiliertes JavaScript mit einem Hash der Quelle für bis zu 5 Garbage Collections gespeichert. Dies bedeutet, dass zwei identische Teile des Quellcodes einen Cache-Eintrag im Speicher gemeinsam nutzen, unabhängig davon, wie sie enthalten waren. Dieser Cache wird nicht gelöscht, wenn Seiten neu geladen werden.

Quelle


Update - 19/03/2015

Das Chrome Team hat veröffentlicht Details zu den neuen Techniken für das Streamen und Zwischenspeichern von JavaScript .

  1. Skript-Streaming

Skript-Streaming optimiert das Parsen von JavaScript-Dateien. [...]

Ab Version 41 analysiert Chrome asynchrone und zurückgestellte Skripte in einem separaten Thread, sobald der Download begonnen hat. Dies bedeutet, dass das Parsen nur Millisekunden nach Abschluss des Downloads abgeschlossen werden kann und zu Seiten führt Laden bis zu 10% schneller.

  1. Code-Caching

Normalerweise kompiliert die V8-Engine das JavaScript der Seite bei jedem Besuch und verwandelt es in Anweisungen, die ein Prozessor versteht. Dieser kompilierte Code wird verworfen, sobald ein Benutzer von der Seite weg navigiert, da der kompilierte Code zum Zeitpunkt der Kompilierung stark vom Status und Kontext des Computers abhängt.

Chrome 42 führt eine erweiterte Technik zum Speichern einer lokalen Kopie des kompilierten Codes ein, sodass die Schritte zum Herunterladen, Parsen und Kompilieren übersprungen werden können, wenn der Nutzer zur Seite zurückkehrt. Auf diese Weise können Sie bei allen Seitenladevorgängen Chrome) etwa 40% der Kompilierungszeit einsparen und wertvollen Akku auf Mobilgeräten sparen.


Opera: Carakan Engine

In der Praxis bedeutet dies, dass wir immer dann, wenn ein Skriptprogramm kompiliert werden soll, dessen Quellcode mit dem eines anderen Programms identisch ist, das kürzlich kompiliert wurde, die vorherige Ausgabe des Compilers wiederverwenden und den Kompilierungsschritt vollständig überspringen. Dieser Cache ist in typischen Browserszenarien sehr effektiv, in denen eine Seite für Seite von derselben Site geladen wird, z. B. verschiedene Nachrichtenartikel von einem Nachrichtendienst, da auf jeder Seite häufig dieselbe, manchmal sehr große Skriptbibliothek geladen wird.

Aus diesem Grund wird JavaScript beim erneuten Laden von Seiten zwischengespeichert. Zwei Anforderungen an dasselbe Skript führen nicht zu einer erneuten Kompilierung.

Quelle


Firefox: SpiderMonkey Engine

SpiderMonkey verwendet Nanojit als systemeigenes Back-End, einen JIT-Compiler. Der Vorgang des Kompilierens des Maschinencodes ist zu sehen hier . Kurz gesagt, es erscheint, um Skripte neu zu kompilieren, wenn sie geladen werden. Wenn jedoch wir schauen genauer hin die Interna von Nanojit betrachtet, sehen wir, dass der übergeordnete Monitor jstracer, der zum Verfolgen der Kompilierung verwendet wird, drei Stufen durchlaufen kann während der Kompilierung einen Vorteil für Nanojit bieten:

Der Ausgangszustand des Trace-Monitors ist die Überwachung. Dies bedeutet, dass Spidermonkey Bytecode interpretiert. Jedes Mal, wenn spidermonkey einen Rückwärtssprung-Bytecode interpretiert, merkt sich der Monitor, wie oft der Sprungziel-Programmzähler (PC) angesprungen wurde. Diese Zahl wird als Trefferzahl für den PC bezeichnet. Wenn die Trefferzahl eines bestimmten PCs einen Schwellenwert erreicht, gilt das Ziel als heiß.

Wenn der Monitor feststellt, dass ein Ziel-PC heiß ist, wird in einer Hash-Tabelle mit Fragmenten geprüft, ob ein Fragment nativen Code für diesen Ziel-PC enthält. Wenn es ein solches Fragment findet, wechselt es in den Ausführungsmodus. Andernfalls wechselt es in den Aufnahmemodus.

Dies bedeutet, dass für hot Codefragmente der native Code zwischengespeichert wird. Das heißt, es muss nicht neu kompiliert werden. Es wird nicht klargestellt, dass diese gehashten nativen Abschnitte zwischen den Seitenaktualisierungen beibehalten werden. Aber ich würde davon ausgehen, dass sie sind. Wenn jemand Belege dafür finden kann, dann ausgezeichnet.

[~ # ~] edit [~ # ~] : Es wurde darauf hingewiesen, dass der Mozilla-Entwickler Boris Zbarsky angegeben hat, dass Gecko kompilierte Skripte nicht zwischenspeichert noch. Entnommen aus this SO answer .


Safari: JavaScriptCore/SquirelFish Engine

Ich denke, dass die beste Antwort für diese Implementierung bereits von jemand anderem gegeben .

Derzeit wird der Bytecode (oder der native Code) nicht zwischengespeichert. Es ist ein
Option, die wir in Betracht gezogen haben. Derzeit ist die Codegenerierung jedoch eine
trivialer Teil der JS-Ausführungszeit (<2%), wir verfolgen also nicht
das im Moment.

Dies wurde von Maciej Stachowiak , dem Hauptentwickler von Safari, geschrieben. Ich denke, wir können das als wahr ansehen.

Ich konnte keine anderen Informationen finden, aber Sie können mehr über die Geschwindigkeitsverbesserungen der neuesten SquirrelFish Extreme - Engine lesen hier oder den Quellcode durchsuchen hier if du fühlst dich abenteuerlustig.


IE: Chakra Engine

Es gibt keine aktuellen Informationen zu IE9s JavaScript Engine (Chakra) in diesem Bereich. Wenn jemand etwas weiß, bitte kommentieren.

Dies ist ziemlich inoffiziell, aber für IEs ältere Engine-Implementierungen stellt Eric Lippert ( ein MS-Entwickler von JScript ) in einer Blog-Antwort fest hier dass:

JScript Classic verhält sich wie eine kompilierte Sprache in dem Sinne, dass wir vor der Ausführung eines JScript Classic-Programms den Code vollständig syntaktisch überprüfen, einen vollständigen Analysebaum generieren und einen Bytecode generieren. Wir führen dann den Bytecode durch einen Bytecode-Interpreter aus. In diesem Sinne ist JScript genauso "kompiliert" wie Java. Der Unterschied besteht darin, dass Sie mit JScript unseren proprietären Bytecode nicht beibehalten oder untersuchen können. Außerdem ist der Bytecode viel höher als der JVM-Bytecode - die JScript Classic-Bytecodesprache ist kaum mehr als eine Linearisierung des Analysebaums, wohingegen der JVM-Bytecode eindeutig für den Betrieb auf einem Stapelcomputer mit niedriger Ebene gedacht ist.

Dies deutet darauf hin, dass der Bytecode in keiner Weise erhalten bleibt und daher der Bytecode nicht zwischengespeichert wird.

333
Jivings

Opera macht es, wie in der anderen Antwort erwähnt. ( Quelle )

Firefox (SpiderMonkey-Engine) speichert keinen Bytecode im Cache. ( Quelle )

WebKit (Safari, Konqueror) speichert keinen Bytecode im Cache. ( Quelle )

Ich bin mir nicht sicher, ob es sich um IE [6/7/8] oder V8 (Chrome) handelt. Ich denke, IE führt möglicherweise eine Art Caching durch, während V8 dies möglicherweise nicht tut. IE ist eine geschlossene Quelle, daher bin ich mir nicht sicher, aber in V8 ist es möglicherweise nicht sinnvoll, "kompilierten" Code zwischenzuspeichern, da sie direkt in Maschinencode kompiliert werden.

12
cha0site

Soweit mir bekannt ist, speichert nur Opera das analysierte JavaScript im Cache. Siehe Abschnitt "Im Cache gespeicherte kompilierte Programme" hier .

3
gsnedders

Es ist nichts wert, dass Google Dart dieses Problem explizit über "Snapshots" angeht - das Ziel ist es, die Initialisierungs- und Ladezeit durch Laden der vorbereiteten Version des Codes zu beschleunigen.

InfoQ hat eine gute Beschreibung @ http://www.infoq.com/articles/google-Dart

2
igrigorik

Der Browser nutzt definitiv das Caching, aber ja, die Browser analysieren das JavaScript jedes Mal, wenn eine Seite aktualisiert wird. Denn wann immer eine Seite vom Browser geladen wird, werden 2 Bäume erstellt. 1. Inhaltsbaum und 2. Renderbaum.

Dieser Render-Baum besteht aus den Informationen zum visuellen Layout der dom-Elemente. Wenn also eine Seite geladen wird, wird das Javascript analysiert, und alle dynamischen Änderungen durch das Javascript wie das Positionieren des dom-Elements, das Anzeigen/Verbergen des Elements und das Hinzufügen/Entfernen des Elements führen dazu, dass der Browser den Render-Baum neu erstellt. Aber die modernen Browser wie FF und chrome behandeln es etwas anders, sie haben das Konzept des inkrementellen Renderns, so dass es immer dann, wenn es dynamische Änderungen durch das js gibt, nur diese Elemente verursacht rendern und neu streichen.

0
Abhidev

Ich denke, die richtige Antwort wäre "nicht immer". Soweit ich weiß, spielen sowohl der Browser als auch der Server eine Rolle bei der Bestimmung, was zwischengespeichert wird. Wenn Sie wirklich brauchen, dass Dateien jedes Mal neu geladen werden, sollten Sie dies (zum Beispiel) in Apache konfigurieren können. Natürlich nehme ich an, dass der Browser des Benutzers so konfiguriert sein könnte, dass er diese Einstellung ignoriert, aber das ist wahrscheinlich unwahrscheinlich.

Daher kann ich mir vorstellen, dass in den meisten praktischen Fällen die Javascript-Dateien selbst zwischengespeichert werden, aber jedes Mal, wenn die Seite geladen wird, dynamisch neu interpretiert werden.

0
Zachary Murray