Heim  >  Artikel  >  Web-Frontend  >  Eine kurze Analyse der Verzögerungs- und Asynchronattribute in Skript-Tags

Eine kurze Analyse der Verzögerungs- und Asynchronattribute in Skript-Tags

高洛峰
高洛峰Original
2016-12-03 13:51:061041Durchsuche

1. Vorwort

Der von meinen Vorgesetzten geschriebene Code lautet wie folgt

<script src="#link("xxxx/xx/home/home.js")" type="text/javascript" async defer></script>

Es hat tatsächlich sowohl Asynchronität als auch Da ich dachte, dass es sich um eine Art schwarze Technologie des älteren Fahrers handeln musste und zwischen den beiden auf jeden Fall eine magische chemische Reaktion stattfinden würde, blätterte ich mit ehrfürchtigem Herzen eilig durch die Bücher und Dokumente und überprüfte sie Bitte beachten Sie zunächst die jeweiligen Definitionen.

2. Machen Sie einige Nachforschungen

Werfen wir zunächst einen Blick auf die Definitionen von „Async“ und „Defer“? Öffnen Sie das Red Book Telescope und dies ist die Einführung

2.1 defer

Der Zweck dieses Attributs besteht darin, anzugeben, dass das Skript bei der Ausführung keinen Einfluss auf die Struktur der Seite hat. Das heißt, das Skript wird vor der Ausführung verzögert, bis die gesamte Seite analysiert wurde. Daher ist das Festlegen des Defer-Attributs im <script>-Element gleichbedeutend mit der Anweisung an den Browser, den Download sofort durchzuführen, die Ausführung jedoch zu verzögern. </script>

Die HTML5-Spezifikation erfordert, dass Skripte in der Reihenfolge ausgeführt werden, in der sie erscheinen, sodass das erste verzögerte Skript vor dem zweiten verzögerten Skript ausgeführt wird und diese beiden Skripte vor dem DOMContentLoaded-Ereignis ausgeführt werden. In Wirklichkeit werden Verzögerungsskripte nicht unbedingt nacheinander ausgeführt, und sie werden auch nicht unbedingt ausgeführt, bevor die DOMContentLoad-Zeit ausgelöst wird. Daher ist es am besten, nur ein Verzögerungsskript einzuschließen.

2.2 async

Dieses Attribut ähnelt „defer“ und wird verwendet, um das Verhalten von Verarbeitungsskripten zu ändern. Ähnlich wie „Defer“ funktioniert Async nur bei externen Skriptdateien und weist den Browser an, die Datei sofort herunterzuladen. Aber im Gegensatz zu „Defer“ ist bei als „async“ gekennzeichneten Skripten nicht garantiert, dass sie in ihrer Reihenfolge ausgeführt werden.

Die zweite Skriptdatei kann vor der ersten Skriptdatei ausgeführt werden. Daher ist es wichtig sicherzustellen, dass beide nicht voneinander abhängig sind. Der Zweck der Angabe des async-Attributs besteht darin, zu verhindern, dass die Seite darauf wartet, dass die beiden Skripte heruntergeladen und ausgeführt werden, wodurch andere Inhalte der Seite asynchron geladen werden.

Zusammenfassend lässt sich sagen, dass diese beiden Attribute dazu führen, dass das Skript-Tag asynchron geladen wird, der Zeitpunkt der Ausführung jedoch unterschiedlich ist. Zitieren eines Bildes aus einer Antwort auf segmentfault

Eine kurze Analyse der Verzögerungs- und Asynchronattribute in Skript-Tags

Die blaue Linie steht für das Lesen im Netzwerk, die rote Linie für die Ausführungszeit, die beide für Skripte gelten .

Das heißt, async ist außer Betrieb, während defer sequentiell ausgeführt wird, was bestimmt, dass async besser für Bibliotheken wie Baidu Analytics oder Google Analytics geeignet ist, die nicht auf andere Skripte angewiesen sind. Aus dem Bild können Sie ersehen, dass das Laden und Parsen eines gewöhnlichen <script>-Tags synchron erfolgt, was das Rendern des DOM blockiert. Deshalb schreiben wir oft <script> Erstens besteht ein weiterer Grund darin, dass js möglicherweise DOM-Vorgänge ausführt, um langfristige weiße Bildschirme durch das Laden von Ressourcen zu verhindern. Daher muss es ausgeführt werden, nachdem alle DOMs gerendert wurden. </script>

2.3 wirklich?

Dieses Bild (fast die einzige auf Baidu gefundene Antwort) ist jedoch nicht streng. Dies ist nur eine Standardsituation, und die meisten Browser nehmen bei der Implementierung Optimierungen vor.

Mal sehen, was Chrome macht. Die der URL entsprechende Webseite.

2. Der Loader verlässt sich auf das Netzwerkmodul, um eine Verbindung herzustellen, Anfragen zu senden und Antworten zu empfangen.


3. WebKit empfängt Daten von verschiedenen Webseiten oder Ressourcen, von denen einige synchron oder asynchron abgerufen werden können.


4. Die Webseite wird an den HTML-Interpreter übergeben und in eine Reihe von Wörtern (Token) umgewandelt.


5. Der Interpreter erstellt Knoten (Node) basierend auf Wörtern, um einen DOM-Baum zu bilden.


6. Wenn es sich bei dem Knoten um JavaScript-Code handelt, rufen Sie die JavaScript-Engine auf, um ihn zu interpretieren und auszuführen.


7. JavaScript-Code kann die Struktur des DOM-Baums ändern.


8. Wenn der Knoten auf andere Ressourcen wie Bilder, CSS, Videos usw. angewiesen ist, rufen Sie den Ressourcenlader auf, um diese zu laden. Sie sind jedoch asynchron und behindern die Fortsetzung nicht Erstellung des aktuellen DOM-Baums; Wenn es sich um eine JavaScript-Ressourcen-URL handelt (nicht als asynchron markiert), müssen Sie die Erstellung des aktuellen DOM-Baums stoppen, bis die JavaScript-Ressource geladen und von der JavaScript-Engine ausgeführt wird, bevor Sie mit der Erstellung fortfahren DOM-Baum.


Im Allgemeinen fordert der Chrome-Browser also zuerst das HTML-Dokument an, ruft dann den entsprechenden Ressourcenlader für die verschiedenen darin enthaltenen Ressourcen auf, um asynchrone Netzwerkanforderungen zu stellen und führt gleichzeitig das DOM-Rendering durch Bis er auf das Tag <script> trifft, stoppt der Hauptprozess das Rendern und wartet auf das Laden der Ressource. Anschließend ruft er die V8-Engine auf, um js zu analysieren, und fährt dann mit der DOM-Analyse fort. Nach meinem Verständnis ist das Hinzufügen des Async-Attributs gleichbedeutend mit dem Öffnen eines separaten Prozesses zum unabhängigen Laden und Ausführen, und „Defer“ hat den gleichen Effekt wie das Platzieren von <script> am Ende von <body>. <p><br/>3. Experiment 1<p>3.1-Demo<p><br/>Um die obige Schlussfolgerung zu überprüfen, testen wir sie <p> <p> <pre class="brush:html;toolbar:false">&lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot;&gt; &lt;head&gt; &lt;meta charset=&quot;UTF-8&quot;&gt; &lt;title&gt;Document&lt;/title&gt; &lt;link href=&quot;http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.css&quot; rel=&quot;stylesheet&quot;&gt; &lt;link href=&quot;http://cdn.staticfile.org/foundation/6.0.1/css/foundation.css&quot; rel=&quot;stylesheet&quot;&gt; &lt;script src=&quot;http://lib.sinaapp.com/js/angular.js/angular-1.2.19/angular.js&quot;&gt;&lt;/script&gt; &lt;script src=&quot;http://libs.baidu.com/backbone/0.9.2/backbone.js&quot;&gt;&lt;/script&gt; &lt;script src=&quot;http://libs.baidu.com/jquery/2.0.0/jquery.js&quot;&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; ul&gt;li{这是第$个节点}*1000 &lt;/body&gt; &lt;/html&gt;</pre><p>Eine einfache Demo, die auf 2 CSS und 3 JS aus verschiedenen CDNs verweist und 1000 LI im Text erstellt. Überprüfen Sie dies mithilfe der Zeitleiste von Chrome, indem Sie den Speicherort externer Referenzressourcen anpassen und relevante Attribute hinzufügen. <p>3.2 In <p><img src="https://img.php.cn//upload/image/696/384/898/1480744154246530.jpg" title="1480744154246530.jpg" alt="Eine kurze Analyse der Verzögerungs- und Asynchronattribute in Skript-Tags"/><p> platziert, lädt Ressourcen asynchron, blockiert jedoch das Rendern von <body> und es erscheint ein weißer Bildschirm Die Bestellung wird sofort ausgeführt. Führen Sie das Skript <p>3.3 aus und platzieren Sie es am Ende von <body>. Laden Sie Ressourcen asynchron, warten Sie auf den Inhalt in <body> Körper> und klicken Sie auf die Schaltfläche „Laden“. Führen Sie JS nacheinander aus<p>3.3 Platzieren Sie es im <head> und verwenden Sie async<img src="https://img.php.cn//upload/image/639/130/331/1480744171245752.jpg" title="1480744171245752.jpg" alt="Eine kurze Analyse der Verzögerungs- und Asynchronattribute in Skript-Tags"/><p><p> asynchron und führen Sie JS-Ressourcen sofort nach dem Laden aus, und zwar nicht, wer schneller ist, wird zuerst gehen<p>3.4 Platzieren Sie es im <head> head und verwenden Sie defer<img src="https://img.php.cn//upload/image/392/809/508/1480744186346776.jpg" title="1480744186346776.jpg" alt="Eine kurze Analyse der Verzögerungs- und Asynchronattribute in Skript-Tags"/><p><p> um Ressourcen nach dem DOM-Rendering asynchron zu laden. Führen Sie dann JS<p>3.5 der Reihe nach aus, platzieren Sie es im <head> head und verwenden Sie gleichzeitig async und defer<img src="https://img.php.cn//upload/image/414/954/733/1480744198930605.jpg" title="1480744198930605.jpg" alt="Eine kurze Analyse der Verzögerungs- und Asynchronattribute in Skript-Tags"/> <p><p>Die Leistung stimmt mit Async überein. Ich habe meine Fantasie genutzt, um die Positionen dieser beiden Attribute auszutauschen, um zu sehen, ob es einen Überlagerungseffekt gibt. Es stellt sich heraus, dass sie konsistent sind = =, <p> Zusammenfassend wird empfohlen, unter der Webkit-Engine < script> am Ende von <body> einzufügen Analytics oder Buliuzi, Sie können das Async-Attribut verwenden. Wenn Ihr <script>-Tag in den Header <head> geschrieben werden muss, können Sie defer-Attribute verwenden <img src="https://img.php.cn//upload/image/312/914/529/1480744214244130.jpg" title="1480744214244130.jpg" alt="Eine kurze Analyse der Verzögerungs- und Asynchronattribute in Skript-Tags"/> Versuchen Sie also, die Psychologie der Senioren herauszufinden, und was ist der Grund für das gleichzeitige Schreiben? <p>Verwenden Sie caniuse, async Es wird im IE<=9 nicht unterstützt, aber Andere Browser sind in Ordnung; Defer wird im IE<=9 unterstützt, aber es wird Fehler geben, und andere Browser sind in Ordnung. Das Phänomen wird in dieser Ausgabe beschrieben, weshalb „Telescope“ nur einen Grund für Defer empfiehlt. Daher sind beide Attribute angegeben, um die Verzögerung zu aktivieren, wenn Async nicht unterstützt wird. In einigen Fällen weist die Verzögerung jedoch immer noch Fehler auf. <p>Das Defer-Attribut kann auch dann angegeben werden, wenn das Async-Attribut angegeben ist, um zu bewirken, dass ältere Webbrowser, die nur Defer (und nicht Async) unterstützen, auf das Defer-Verhalten zurückgreifen, anstatt auf das synchrone Blockierungsverhalten, das das ist Standard.<p>5. Fazit<br/><p>Tatsächlich ist es am sichersten, am Ende von <body> zu schreiben Tünchen. Bildschirmproblem, kein Problem mit der Ausführungsreihenfolge, lehnen Sie sich zurück und machen Sie sich keine Sorgen mit Verzögerung und Asynchronität.<p>Derzeit habe ich nur den Rendering-Mechanismus des Chrome-Webkits studiert, Firefox und IE müssen damit fortfahren Studie, Bilder und CSS und andere Darstellung externer Ressourcen müssen noch untersucht werden. <p><p></script>
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