Maison >interface Web >js tutoriel >Analyse du chargement et de l'exécution de scripts JavaScript dans un environnement de navigateur : caractéristiques différées et asynchrones_compétences Javascript
Les fonctionnalités de report et async sont considérées comme deux fonctionnalités que de nombreux développeurs JavaScript sont "familières mais pas familières". D'un point de vue littéral, les fonctions des deux sont faciles à comprendre. et "script asynchrone" respectivement. Cependant, en prenant le report comme exemple, les développeurs ne sont pas nécessairement familiers avec certains détails, tels que : quand un script avec la fonctionnalité defer sera-t-il retardé pour être exécuté ; si les scripts internes et les scripts externes peuvent prendre en charge les scripts defer après le report ; en plus de l'exécution différée, quelles sont les particularités, etc. Cet article combine certains articles existants et la description des deux fonctionnalités dans les documents MDN pour mener une étude plus complète et un résumé du report et de l'async, dans l'espoir d'aider les développeurs à mieux maîtriser ces deux fonctionnalités.
1 Introduction
Dans "Analyse du chargement et de l'exécution du script JavaScript dans l'environnement du navigateur : séquence d'exécution du code" nous avons mentionné que l'exécution du code JavaScript bloquera l'analyse et le rendu de la page ainsi que le téléchargement d'autres ressources. . Bien sûr, étant donné que JavaScript est un langage monothread, ce qui signifie que dans des circonstances normales, le code JavaScript d'une page ne peut être exécuté que dans l'ordre de haut en bas. Bien sûr, comme dans " Analyse de JavaScript. Chargement et exécution du script dans l'environnement du navigateur Comme nous l'avons analysé dans « Séquence d'exécution », dans certains cas, par exemple lors de la saisie d'un script via document.write ou de l'introduction d'un script via la technologie de script dynamique, l'ordre d'exécution du code JavaScript ne ne suivent pas nécessairement l'ordre strict de haut en bas. le report et l'async sont aussi ce que nous appelons des « situations anormales ».
Nous disons souvent que l'exécution de JavaScript est bloquante. Dans le développement réel, le blocage qui nous préoccupe généralement le plus et celui qui affecte le plus l'expérience utilisateur devrait être les aspects suivants :
[1] Blocage de l'analyse et du rendu des pages
[2] Le script d'initialisation de la page que nous avons écrit (généralement le script destiné à écouter l'événement DOMContentLoaded). Cette partie du script est le script que nous souhaitons exécuter en premier, car nous écrirons le code le plus pertinent pour l'interaction de l'utilisateur. ici. )
[3] Blocage du téléchargement de ressources externes sur la page (telles que des images)
Si nous avons une opération de script qui prend du temps et que ce script bloque les trois endroits que nous avons mentionnés ci-dessus, alors les performances ou l'expérience utilisateur de cette page Web seront très mauvaises.
L'intention initiale des deux fonctionnalités defer et async est également de résoudre ou d'atténuer l'impact du blocage sur l'expérience de la page. Analysons ces deux fonctionnalités ci-dessous. Nous comprenons ces deux principalement sous les aspects suivants :
Fonction de 2 reports
2.1 À propos du timing d'exécution du script de report
.
2.2 différer la prise en charge du navigateur
Jetons un coup d'œil à la prise en charge par les navigateurs de la fonctionnalité de report :
Il y a un bug dans les navigateurs IE9 et inférieurs, qui sera expliqué en détail plus tard dans la DÉMO.
2.3 DÉMO : Vérification du fonctionnement de la fonction de report
Nous imitons la méthode utilisée par Olivier Rochard dans "le script defer attribut" pour vérifier la fonction de l'attribut defer :
Nous avons d'abord préparé 6 scripts externes :
1.js:
test = "Je suis responsable du script externe n"
2.js
test = "Je suis un corps externe script n"
3.js
test = "Je suis le script externe du bas n"
defer1.js
test = "Je suis responsable du script de delay externe n"
;
defer2.js
test = "Je suis un script de retard externe du corps n"
;
defer3.js
test = "Je suis le script de retard externe inférieur n"
;
Le code en HTML est :
<!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>
Dans le code, afin de faciliter l'implémentation de l'événement DOMContentLoaded, nous avons introduit jQuery (des articles ultérieurs expliqueront comment implémenter vous-même un DOMContentLoaded compatible. Ensuite, nous avons introduit des scripts de retard dans la tête, à l'intérieur du corps et à l'extérieur du). corps du script et des scripts normaux, et enregistre l'état d'exécution de chaque morceau de code via une chaîne globale. Jetons un coup d'œil aux résultats d'exécution dans chaque navigateur :
.
IE7 | IE9 | IE10 | CHROME | firefox | ||||||||||
|
Je suis responsable script externe Je suis responsable du script interne Je suis un script externe au corps Je suis le script externe du bas Je suis responsable du script de delay externe Je suis responsable du script interne du retard Je suis un script de retard externe au corps Je suis le script de delay externe du bas Je suis le script dans DOMContentLoaded Je suis le script dans window.onload | Je suis responsable script externe Je suis en tête du script interne retardé Je suis responsable du script interne Je suis un script externe au corps Je suis le script externe du bas Je suis responsable du script de delay externe Je suis un script de retard externe au corps Je suis le script de delay externe du bas Je suis le script dans DOMContentLoaded Je suis le script dans window.onload | Je suis responsable script externe Je suis en tête du script interne retardé Je suis responsable du script interne Je suis un script externe au corps Je suis le script externe du bas Je suis responsable du script de delay externe Je suis un script de retard externe au corps Je suis le script de delay externe du bas Je suis le script dans DOMContentLoaded Je suis le script dans 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个脚本,然而在IE77f5db5c498cd8790c183e49397570fd 요소가 defer 및 async 속성을 모두 정의하는 경우 비동기로 처리됩니다(참고: 비동기를 지원하지 않는 브라우저는 비동기 속성을 직접 무시합니다)
[2] 3f1c4e4b6b16bbbd69b2ee476dc4f83a 요소가 defer만 정의하는 경우 지연된 스크립트로 처리됩니다.
[3] 3f1c4e4b6b16bbbd69b2ee476dc4f83a 요소가 defer 또는 async를 정의하지 않으면 정상적으로 처리됩니다. 즉, 스크립트가 즉시 로드되고 실행됩니다.