Heim  >  Artikel  >  Web-Frontend  >  Eine kurze Analyse des setTimeou-Thread-Mechanismus

Eine kurze Analyse des setTimeou-Thread-Mechanismus

一个新手
一个新手Original
2017-09-09 09:16:221116Durchsuche

Als ich das Buch High Performance JavaScript las, sah ich diesen Satz:

Das Platzieren von Skripten oben auf der Seite auf diese Weise führt normalerweise zu einer spürbaren Verzögerung, oft in Form eines leeren Weiß Seite, bevor der Benutzer überhaupt beginnen kann, die Seite zu lesen oder anderweitig mit ihr zu interagieren, wird wie folgt erklärt:

Das Platzieren des Skripts im Kopf führt zu einer erheblichen Verzögerung, normalerweise wie folgt: Die Die Seite wird leer geöffnet und der Benutzer kann sie nicht lesen oder damit interagieren.

Mein Verständnis ist: Wenn Sie js im Kopf platzieren, führt das Laden und Ausführen von js zu einer Verzögerung beim Rendern der Seite. Wenn js am Ende platziert wird, kann es dem Benutzer zuerst angezeigt werden, ohne dass es durch die Blockierung von js beeinträchtigt wird, da das Rendern der Seite dem Laden oder Ausführen von js vorausgeht.

Um dies zu überprüfen, wurde das folgende Experiment durchgeführt:

Die experimentellen Ergebnisse sind interessant: Hallo Welt wartete 5 Sekunden, bevor es herauskam.
<p>hello world</p><script type="text/javascript">  
    function f() {    
    var t = +new Date();

    //运行5秒    while(true) {
      if(+new Date() - t > 5) {
        break;
      }
    }
  }
  f();  // ①</script>

Eingehende Überprüfung: Führen Sie das obige Skript als externen js-Link ein oder laden Sie es dynamisch. Nach 5 Sekunden Wartezeit kam das Ergebnis immer noch heraus.

Das bedeutet, dass das Rendern der Seite erfolgen muss, nachdem alle js geladen und ausgeführt wurden. Mit dem obigen Absatz stimmt etwas nicht.

Bedeutet dies, dass die Platzierung am Kopf und am Ende des js den gleichen Effekt hat, solange js keine DOM-Operationen beinhaltet? Natürlich nicht. Wenn beispielsweise Bilder oder andere Ressourcen im HTML-Code vorhanden sind und js am Anfang platziert wird, muss der Download des Bildes warten, bis js vollständig ausgeführt wird, bevor er gestartet wird Das Herunterladen des Bildes blockiert nicht die Ausführung von js. Sie können das parallele Herunterladen von Bildern und die Ausführung von js erreichen.

Ist das das Ende des Problems? Natürlich nicht. Ein sehr wichtiger Teil der Front-End-Arbeit ist die Leistungsoptimierung. Also dachte ich an setTimeout.

setTimeout wird verwendet, um die Ausführung von JS-Code zu verzögern. Es hat den Vorteil, dass es die Ausführung von JS dahinter nicht blockiert. Daher vermute ich, dass setTimeout auch das Rendern der Seite nicht blockieren wird.

Option 1: Ersetzen Sie den ①-Teil oben durch:

 setTimeout(f,0);
Infolgedessen muss „hello world“ noch 5 Sekunden warten, bevor es herauskommt. Wenn Sie jedoch vorsichtig sind, werden Sie feststellen, dass das Ladesymbol auf der Browserbeschriftung fehlt.

Raten Sie weiter, 0 ist zu klein, was dazu führt, dass der Browser feststellt, dass sich hinter setTimeout kein JS-Code befindet, und den Inhalt in setTimeout, also die f-Funktion, sofort ausführt. Ändern Sie also die Zeit auf 100 ms.

Option 2: Ersetzen Sie den ①-Teil oben durch:

setTimeout(f, 100);
Als Ergebnis erscheint sofort „Hallo Welt“. Ein bisschen aufgeregt. Interessierte Schüler können mit dem Testen fortfahren. Sie werden feststellen, dass es einen kritischen Wert gibt (verschiedene Browser haben unterschiedliche kritische Werte, wenn der zweite Parameter größer als dieser kritische Wert ist). Andernfalls wird „Hallo Welt“ angezeigt , Sie müssen warten. Es wird angezeigt, nachdem die darin enthaltene Funktion abgeschlossen ist.

Das ist erstaunlich, warum passiert das? Um diese Frage zu beantworten, müssen wir den Threading-Mechanismus des Browsers untersuchen.

Wir wissen, dass es im Browser mindestens zwei Threads gibt: den Thread, der js analysiert, und den Thread, der die Schnittstelle rendert. Hier nennen wir sie vorübergehend JS-Thread und UI-Thread.

Da js das DOM manipulieren kann, werden die Elementdaten vorher und nachher erhalten, wenn Sie die Attribute dieser Elemente beim Rendern der Schnittstelle ändern (dh der JS-Thread und der UI-Thread werden gleichzeitig ausgeführt). Der Rendering-Thread ist möglicherweise inkonsistent. Um unvorhersehbare Rendering-Ergebnisse zu verhindern, steuert der Browser daher den JS-Thread und den UI-Thread so, dass sie synchron in einer Warteschlange ausgeführt werden.

Zurück zur obigen Frage: Wenn setTimeout ausgeführt wird, wird genau dann ein neuer Timer-Thread geöffnet, wenn der JS-Thread abgeschlossen ist sofort (dh die Zeit ist kleiner als der oben genannte kritische Wert). Um die schlechte Erfahrung zu vermeiden, die durch die schwerwiegende Verzögerung von setTimeout verursacht wird, die durch zu lange Ausführung des UI-Threads verursacht wird, wartet der Browser, bis setTimeout abläuft Dann wird das JS darin ausgeführt. Wenn festgestellt wird, dass der Ablauf von setTimeout lange dauert, wechselt der Browser sofort zum UI-Thread, um Zeitverschwendung zu vermeiden.

Fazit: Mit setTimeout kann zeitaufwändiger JS-Code verarbeitet werden. Achten Sie jedoch darauf, den zweiten Parameter nicht zu klein einzustellen, da sonst dieselbe leere Seite angezeigt wird. Es wird empfohlen, etwa 100 ms zu betragen, was allen Browsern gerecht wird. Wenn Sie nicht mit dem IE kompatibel sind, ist es natürlich eine gute Wahl, auf setTimeout zu verzichten und Web-Worker zu verwenden.

In HTML4 sind von js erstellte Programme Single-Threaded-Web-Worker, eine Technologie, die zur Implementierung der Hintergrundverarbeitung in Webanwendungen verwendet wird. Mit dieser API ist es sehr einfach, im Hintergrund laufende Threads zu erstellen:

Das obige ist der detaillierte Inhalt vonEine kurze Analyse des setTimeou-Thread-Mechanismus. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn