Heim >Web-Frontend >js-Tutorial >Analyse des Ladens und Ausführens von JavaScript-Skripten in einer Browserumgebung: Eigenschaften verzögern und asynchronisieren_Javascript-Fähigkeiten

Analyse des Ladens und Ausführens von JavaScript-Skripten in einer Browserumgebung: Eigenschaften verzögern und asynchronisieren_Javascript-Fähigkeiten

WBOY
WBOYOriginal
2016-05-16 15:20:021672Durchsuche

Es wird angenommen, dass es sich bei den Verzögerungs- und Asynchronisierungsfunktionen um zwei Funktionen handelt, mit denen viele JavaScript-Entwickler „vertraut, aber nicht vertraut“ sind. Im wahrsten Sinne des Wortes sind die Funktionen der beiden leicht zu verstehen. bzw. „asynchrones Skript“. Am Beispiel der Verzögerung sind Entwickler jedoch möglicherweise nicht unbedingt mit einigen Details vertraut, z. B.: Wann wird die Ausführung eines Skripts mit der Verzögerungsfunktion verzögert? Zusätzlich zur verzögerten Ausführung, was sind die Besonderheiten usw. Dieser Artikel kombiniert einige vorhandene Artikel und die Beschreibung der beiden Funktionen in MDN-Dokumenten, um eine umfassendere Studie und Zusammenfassung von Defer und Async durchzuführen und Entwicklern dabei zu helfen, diese beiden Funktionen besser zu beherrschen.

1 Einleitung

In „Analyse des Ladens und Ausführens von JavaScript-Skripten in der Browserumgebung: Codeausführungssequenz“ haben wir erwähnt, dass die Ausführung von JavaScript-Code das Parsen und Rendern der Seite sowie das Herunterladen anderer Ressourcen blockiert Da es sich bei JavaScript um eine Single-Thread-Sprache handelt, kann der JavaScript-Code auf einer Seite natürlich nur in der Reihenfolge „Analyse von JavaScript“ ausgeführt werden Laden und Ausführen von Skripten in der Browserumgebung Wie wir in „Ausführungssequenz “ analysiert haben, ist die Ausführungsreihenfolge von JavaScript-Code in einigen Fällen, beispielsweise bei der Eingabe eines Skripts über document.write oder der Einführung eines Skripts über dynamische Skripttechnologie, unterschiedlich Nicht unbedingt die strikte Reihenfolge von oben nach unten einhalten und asynchronisieren sind auch das, was wir als „abnormale Situationen“ bezeichnen.

Wir sagen oft, dass die Ausführung von JavaScript blockiert. In der tatsächlichen Entwicklung sollten die folgenden Aspekte die Blockierung sein, die uns normalerweise am meisten beschäftigt und die das Benutzererlebnis am meisten beeinträchtigt:

[1] Blockierung der Seitenanalyse und -wiedergabe

[2] Das von uns geschriebene Seiteninitialisierungsskript (im Allgemeinen das Skript, das das DOMContentLoaded-Ereignis abhört). Dieser Teil des Skripts ist der Skript, den wir zuerst ausführen möchten, da wir den Code schreiben, der für die Benutzerinteraktion am relevantesten ist hier. )

[3] Blockierung des Herunterladens externer Ressourcen auf der Seite (z. B. Bilder)

Wenn wir einen zeitaufwändigen Skriptvorgang haben und dieses Skript die drei oben genannten Stellen blockiert, ist die Leistung oder Benutzererfahrung dieser Webseite sehr schlecht.

Die ursprüngliche Absicht der beiden Funktionen „Defer“ und „Async“ besteht auch darin, die Auswirkungen des Blockierens auf das Seitenerlebnis zu lösen oder zu mildern. Wir verstehen diese beiden Funktionen hauptsächlich unter folgenden Gesichtspunkten: >

[1]Wann ist die Ausführungszeit verzögerter oder asynchroner Skripte? Was ist mit der Seitenblockierung?


[2] Können sowohl interne als auch externe Skripte verzögert oder asynchron implementiert werden?


[3] Wie gut unterstützen Browser diese beiden Funktionen? Gibt es damit zusammenhängende Fehler?


[4] Muss bei der Verwendung von Skripten, die diese beiden Funktionen verwenden, noch etwas beachtet werden?


2-Verzögerungsfunktion

2.1 Informationen zum Ausführungszeitpunkt des Verzögerungsskripts

Die Verzögerungsfunktion ist eine erweiterte Funktion, die in der HTML4-Spezifikation definiert ist. Ursprünglich wurde sie nur von IE4 und Firefox 3.5 unterstützt. Später wurde sie auch von Browsern wie Chrome unterstützt, die defer="defer" verwenden. defer bedeutet Verzögerung, was bedeutet, dass die Ausführung des Skripts verzögert wird. Unter normalen Umständen wird das von uns eingeführte Skript sofort heruntergeladen und ausgeführt. Mit der Verzögerungsfunktion wird das Skript jedoch nicht sofort nach dem Herunterladen ausgeführt, sondern nach dem Parsen der Seite. Werfen wir einen Blick auf die Erklärung des HTML4-Standards zur Verzögerung:


defer: Wenn dieses boolesche Attribut festgelegt ist, gibt es dem Benutzeragenten einen Hinweis, dass das Skript keinen Dokumentinhalt generieren wird (z. B. kein „document.write“ in Javascript) und der Benutzeragent daher mit der Analyse fortfahren kann und Rendern.


Mit anderen Worten: Wenn die Verzögerung festgelegt ist, teilt es dem Benutzeragenten mit, dass dieses Skript keinen Dokumentinhalt erzeugen wird, sodass der Benutzeragent weiterhin analysieren und rendern kann. Schauen wir uns noch einmal die Schlüsselbeschreibung von defer in MDN an:


defer: Wenn das async-Attribut nicht vorhanden ist, aber das defer-Attribut vorhanden ist, wird das Skript ausgeführt, wenn die Seite mit dem Parsen fertig ist


Durch die Definition im Standard können wir klarstellen, dass das Verzögerungsskript das Parsen der Seite nicht blockiert, sondern mit der Ausführung wartet, bis das Parsen der Seite abgeschlossen ist. Das zeitaufwändige Verzögerungsskript kann jedoch trotzdem ausgeführt werden Blockieren Sie den Download externer Ressourcen. Wird dadurch das DOMContentLoaded-Ereignis blockiert? Tatsächlich wird das Verzögerungsskript immer noch vor dem DOMContentLoaded-Ereignis ausgeführt, sodass das Skript weiterhin in DOMContentLoaded blockiert wird. Wir können die folgende Abbildung verwenden, um den Ausführungszeitpunkt des Verzögerungsskripts zu verstehen:



Gemäß der Definition im Standard unterstützen interne Skripte keine Verzögerung, aber Browser IE9 und niedriger bieten Verzögerungsunterstützung für interne Skripte.


2.2 Browser-Unterstützung zurückstellen

Werfen wir einen Blick auf die Browserunterstützung für die Verzögerungsfunktion:


Es gibt einen Fehler in IE9 und niedrigeren Browsern, der später in der DEMO ausführlich erläutert wird.

2.3 DEMO: Funktionsüberprüfung der Verzögerungsfunktion

Wir imitieren die von Olivier Rochard im „Skript-Defer-Attribut“ verwendete Methode, um die Funktion des Defer-Attributs zu überprüfen:

Zuerst haben wir 6 externe Skripte vorbereitet:

1.js:

test = „Ich bin Leiter externes Skript n“;

2.js


test = „Ich bin ein Körper externes Skript n“;


3.js


test = „Ich bin das unterste externe Skript n“;

defer1.js

test = „Ich bin Leiter des externen Verzögerungsskripts n“;

defer2.js


test = „Ich bin ein externes Verzögerungsskript n“;


defer3.js


test = „Ich bin das unterste externe Verzögerungsskript n“;

Der Code in HTML lautet:


Um die Implementierung des DOMContentLoaded-Ereignisses zu erleichtern, haben wir jQuery eingeführt (in späteren Artikeln erfahren Sie, wie Sie kompatibles DOMContentLoaded selbst implementieren. Anschließend haben wir Verzögerungsskripte im Kopf, innerhalb des Körpers und außerhalb des Codes eingeführt). Hauptteil des Skripts und normaler Skripte und zeichnet den Ausführungsstatus jedes Codeabschnitts über eine globale Zeichenfolge auf. Werfen wir einen Blick auf die Ausführungsergebnisse in jedem Browser:

IE7 IE9 IE10 CHROM Firefox
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>defer attribute test</title>
<script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
<script type="text/javascript">var test = "";</script>
<script src="defer1.js" type="text/javascript" defer="defer"></script>
<script src="1.js" type="text/javascript"></script>
<script defer="defer">
test += "我是head延迟内部脚本\n";
</script>
<script>
test += "我是head内部脚本\n";
</script>
</head>
<body>
<button id="test">点击一下</button>
<script src="defer2.js" type="text/javascript" defer="defer"></script>
<script src="2.js" type="text/javascript"></script>
</body>
<script src="defer3.js" type="text/javascript" defer="defer"></script>
<script src="3.js" type="text/javascript"></script>
<script>
$(function(){
test += "我是DOMContentLoaded里面的脚本
";
})
window.onload = function(){
test += "我是window.onload里面的脚本
";
var button = document.getElementById("test");
button.onclick = function(){
alert(test);
}
}
</script>
</html> 
Ich bin Leiter des externen Skripts Ich bin der Leiter des internen Skripts

Ich bin ein körperfremdes Skript
Ich bin das unterste externe Skript

Ich bin der Leiter des externen Verzögerungsskripts

Ich bin Kopfverzögerung internes Skript

IE7 IE9 IE10 CHROME firefox

我是head外部脚本
我是head内部脚本
我是body外部脚本
我是底部外部脚本
我是head外部延迟脚本
我是head延迟内部脚本
我是body外部延迟脚本
我是底部外部延迟脚本
我是DOMContentLoaded里面的脚本
我是window.onload里面的脚本

我是head外部脚本
我是head内部脚本
我是body外部脚本
我是底部外部脚本
我是head外部延迟脚本
我是head延迟内部脚本
我是body外部延迟脚本
我是底部外部延迟脚本
我是DOMContentLoaded里面的脚本
我是window.onload里面的脚本

我是head外部脚本
我是head延迟内部脚本
我是head内部脚本
我是body外部脚本
我是底部外部脚本
我是head外部延迟脚本
我是body外部延迟脚本
我是底部外部延迟脚本
我是DOMContentLoaded里面的脚本
我是window.onload里面的脚本

我是head外部脚本
我是head延迟内部脚本
我是head内部脚本
我是body外部脚本
我是底部外部脚本
我是head外部延迟脚本
我是body外部延迟脚本
我是底部外部延迟脚本
我是DOMContentLoaded里面的脚本
我是window.onload里面的脚本

<br />我是head外部脚本
<span style="color: rgb(255,0,0)">我是head延迟内部脚本</span>
我是head内部脚本
我是body外部脚本
我是底部外部脚本
我是head外部延迟脚本
我是body外部延迟脚本
我是底部外部延迟脚本
<span style="color: rgb(255,0,0)">我是DOMContentLoaded里面的脚本
我是window.onload里面的脚本</span>
Ich bin ein Body-External-Delay-Skript Ich bin das unterste externe Verzögerungsskript Ich bin das Skript in DOMContentLoaded Ich bin das Skript in window.onload
Ich bin Leiter des externen Skripts Ich bin der Leiter des internen Skripts Ich bin ein körperfremdes Skript Ich bin das unterste externe Skript Ich bin der Leiter des externen Verzögerungsskripts Ich bin Kopfverzögerung internes Skript Ich bin ein Body-External-Delay-Skript Ich bin das unterste externe Verzögerungsskript Ich bin das Skript in DOMContentLoaded Ich bin das Skript in window.onload Ich bin Leiter des externen Skripts Ich bin ein kopfverzögertes internes Skript Ich bin der Leiter des internen Skripts Ich bin ein körperfremdes Skript Ich bin das unterste externe Skript Ich bin der Leiter des externen Verzögerungsskripts Ich bin ein Body-External-Delay-Skript Ich bin das unterste externe Verzögerungsskript Ich bin das Skript in DOMContentLoaded Ich bin das Skript in window.onload Ich bin Leiter des externen Skripts Ich bin ein kopfverzögertes internes Skript Ich bin der Leiter des internen Skripts Ich bin ein körperfremdes Skript Ich bin das unterste externe Skript Ich bin der Leiter des externen Verzögerungsskripts Ich bin ein Body-External-Delay-Skript Ich bin das unterste externe Verzögerungsskript Ich bin das Skript in DOMContentLoaded Ich bin das Skript in window.onload

从输出的结果中我们可以确定,只有IE9及以下浏览器支持内部延迟脚本,并且defer后的脚本都会在DOMContentLoaded事件之前触发,因此也是会堵塞DOMContentLoaded事件的。

2.4 DEMO:IE0f630a08ba48c70580451c5807d38ff4我是后来加入的16b28748ea4df4d9c2150843fecfba68";
document.body.innerHTML += "7a6bc4f2a125532aca32e87dac970576我是后来加入的16b28748ea4df4d9c2150843fecfba68";
document.body.innerHTML += "7a6bc4f2a125532aca32e87dac970576我是后来加入的16b28748ea4df4d9c2150843fecfba68";
document.body.innerHTML += "7a6bc4f2a125532aca32e87dac970576我是后来加入的16b28748ea4df4d9c2150843fecfba68";
document.body.innerHTML += "7a6bc4f2a125532aca32e87dac970576我是后来加入的16b28748ea4df4d9c2150843fecfba68";
document.body.innerHTML += "7a6bc4f2a125532aca32e87dac970576我是后来加入的16b28748ea4df4d9c2150843fecfba68";
document.body.innerHTML += "7a6bc4f2a125532aca32e87dac970576我是后来加入的16b28748ea4df4d9c2150843fecfba68";
alert("我是第1个脚本");

2.js

alert("我是第2个脚本");

修改HMTL中的代码为:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>defer bug in IE=9 test</title>
<script src="1.js" type="text/javascript" defer="defer"></script>
<script src="2.js" type="text/javascript" defer="defer"></script>
</head>
<body>
</body>
</html>

正常情况下,浏览器中弹出框的顺序肯定是:我是第1个脚本-》我是第2个脚本,然而在IE15f06a32792b596f8d1f07afb1946fb8 mentakrifkan kedua-dua atribut defer dan async, ia akan diproses sebagai async (nota: penyemak imbas yang tidak menyokong async akan langsung mengabaikan atribut async)

[2] Jika elemen 855348821b2e8f2cc4b633bf98f064df hanya mentakrifkan penangguhan, ia akan diproses sebagai skrip tertunda

[3] Jika elemen 855348821b2e8f2cc4b633bf98f064df tidak mentakrifkan tangguh atau tak segerak, ia akan diproses seperti biasa, iaitu: skrip akan dimuatkan dan dilaksanakan serta-merta

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