Rumah >hujung hadapan web >tutorial js >Analisis pemuatan dan pelaksanaan skrip JavaScript dalam persekitaran penyemak imbas: tangguh dan ciri async_kemahiran javascript

Analisis pemuatan dan pelaksanaan skrip JavaScript dalam persekitaran penyemak imbas: tangguh dan ciri async_kemahiran javascript

WBOY
WBOYasal
2016-05-16 15:20:021645semak imbas

Ciri tangguh dan tak segerak dipercayai merupakan dua ciri yang kebanyakan pembangun JavaScript "biasa tetapi tidak biasa dengannya". dan kesan "skrip tak segerak". Walau bagaimanapun, mengambil penangguhan sebagai contoh, pembangun mungkin tidak semestinya mengetahui beberapa butiran, seperti: bilakah skrip dengan ciri penangguhan akan ditangguhkan untuk dilaksanakan sama ada skrip dalaman dan skrip luaran boleh menyokong penangguhan; selain pelaksanaan tertangguh, apakah ciri khasnya, dsb. Artikel ini menggabungkan beberapa artikel sedia ada dan perihalan dua ciri dalam dokumen MDN untuk menjalankan kajian dan ringkasan penangguhan dan async yang lebih komprehensif, dengan harapan dapat membantu pembangun menguasai kedua-dua ciri ini dengan lebih baik.

1 Pengenalan

Dalam "Analisis Pemuatan dan Pelaksanaan Skrip JavaScript dalam Persekitaran Pelayar: Urutan Pelaksanaan Kod" kami menyebut bahawa pelaksanaan kod JavaScript akan menyekat penghuraian dan pemaparan halaman serta memuat turun sumber lain . Sudah tentu, kerana JavaScript adalah bahasa berutas tunggal, yang bermaksud bahawa dalam keadaan biasa, kod JavaScript dalam halaman hanya boleh dilaksanakan mengikut urutan dari atas ke bawah Sudah tentu, seperti dalam " Analisis JavaScript Pemuatan dan Pelaksanaan Skrip dalam Persekitaran Penyemak Imbas Seperti yang kami analisis dalam "Jujukan Pelaksanaan ", dalam beberapa kes, seperti apabila memasukkan skrip melalui document.write atau memperkenalkan skrip melalui teknologi skrip dinamik, susunan pelaksanaan kod JavaScript tidak tidak semestinya mengikut perintah yang ketat dari atas ke bawah dan async juga yang kita panggil "situasi tidak normal".

Kami sering mengatakan bahawa pelaksanaan JavaScript adalah menyekat Dalam pembangunan sebenar, penyekatan yang biasanya paling kami bimbangkan dan penyekatan yang paling mempengaruhi pengalaman pengguna haruslah aspek berikut:

[1] Menyekat penghuraian dan pemaparan halaman

[2] Skrip permulaan halaman yang kami tulis (biasanya skrip terikat untuk mendengar acara DOMContentLoaded ini ialah skrip yang kami mahu laksanakan dahulu, kerana kami akan menulis kod yang paling berkaitan dengan interaksi pengguna). di sini.)

[3] Menyekat muat turun sumber luaran pada halaman (seperti gambar)

Jika kami mempunyai operasi skrip yang memakan masa, dan skrip ini menyekat tiga tempat yang kami nyatakan di atas, maka prestasi atau pengalaman pengguna halaman web ini akan menjadi sangat lemah.

Niat asal kedua-dua ciri penangguhan dan async juga adalah untuk menyelesaikan atau mengurangkan kesan penyekatan pada pengalaman halaman Mari kita menganalisis kedua-dua ciri ini terutamanya dari aspek berikut >

[1]Bilakah masa pelaksanaan skrip tertangguh atau tak segerak? Bagaimana pula dengan penyekatan halaman?


[2] Adakah kedua-dua skrip dalaman dan luaran mampu melambatkan atau pelaksanaan tak segerak?


[3] Sejauh manakah pelayar menyokong kedua-dua ciri ini? Adakah terdapat sebarang pepijat yang berkaitan?


[4] Adakah terdapat perkara lain yang perlu diberi perhatian apabila menggunakan skrip yang menggunakan kedua-dua ciri ini?


2 ciri tangguh

2.1 Mengenai masa pelaksanaan skrip penangguhan

Ciri tangguh ialah ciri lanjutan yang ditakrifkan dalam spesifikasi HTML4 Pada mulanya, ia hanya disokong oleh IE4 dan Firefox3.5 Kemudian, pelayar seperti Chrome turut menambah sokongan untuknya, menggunakan defer="defer". defer bermaksud kelewatan, yang bermaksud ia akan menangguhkan pelaksanaan skrip. Dalam keadaan biasa, skrip yang kami perkenalkan akan dimuat turun dan dilaksanakan dengan serta-merta Namun, dengan ciri tangguh, skrip tidak akan dilaksanakan serta-merta selepas dimuat turun, tetapi akan dilaksanakan selepas halaman dihuraikan. Mari kita lihat penjelasan standard HTML4 tentang penangguhan:


tunda: Apabila ditetapkan, atribut boolean ini memberikan petunjuk kepada ejen pengguna bahawa skrip tidak akan menjana sebarang kandungan dokumen (cth., tiada "document.write" dalam javascript) dan dengan itu, ejen pengguna boleh meneruskan penghuraian dan rendering.


Dalam erti kata lain, jika penangguhan ditetapkan, ia memberitahu ejen pengguna bahawa skrip ini tidak akan menghasilkan sebarang kandungan dokumen, supaya ejen pengguna boleh terus menghuraikan dan membuat persembahan. Mari kita lihat sekali lagi perihalan utama penangguhan dalam MDN:


tunda: Jika atribut async tidak ada tetapi atribut tangguh ada, maka skrip dilaksanakan apabila halaman telah selesai menghuraikan


Melalui takrifan dalam standard, kami boleh menjelaskan dengan jelas bahawa skrip tangguh tidak akan menyekat penghuraian halaman, tetapi akan menunggu sehingga penghuraian halaman selesai sebelum melaksanakannya, bagaimanapun, penangguhan yang memakan masa mungkin masih menyekat muat turun sumber luaran, kemudian Adakah ia akan menyekat acara DOMContentLoaded? Malah, skrip tangguh masih dilaksanakan sebelum acara DOMContentLoaded, jadi ia masih akan menyekat skrip dalam DOMContentLoaded. Kita boleh menggunakan angka berikut untuk membantu memahami masa pelaksanaan skrip tangguh:



Menurut definisi dalam standard, skrip dalaman tidak menyokong penangguhan, tetapi pelayar IE9 dan ke bawah menyediakan sokongan penangguhan untuk skrip dalaman.


2.2 menangguhkan sokongan penyemak imbas

Mari kita lihat sokongan penyemak imbas untuk ciri tangguh:


Terdapat pepijat dalam pelayar IE9 dan di bawah, yang akan diterangkan secara terperinci dalam DEMO nanti.

2.3 DEMO: Pengesahan fungsi ciri tangguh

Kami meniru kaedah yang digunakan oleh Olivier Rochard dalam "atribut penangguhan skrip" untuk mengesahkan fungsi atribut penangguhan:

Mula-mula kami menyediakan 6 skrip luaran:

1.js:

ujian = "Saya ketua skrip luaran n";

2.js


ujian = "Saya adalah skrip luaran badan";


3.js


ujian = "Saya adalah skrip luar bawah n";

tangguh1.js

ujian = "Saya mengetuai skrip kelewatan luaran n";

tunda2.js


ujian = "Saya skrip kelewatan luar badan n";


tunda3.js


ujian = "Saya adalah skrip kelewatan luaran bahagian bawah";

Kod dalam HTML ialah:


Dalam kod, untuk memudahkan pelaksanaan acara DOMContentLoaded, kami memperkenalkan jQuery (artikel kemudian akan memperkenalkan cara untuk melaksanakan sendiri DOMContentLoaded yang serasi Kemudian, kami memperkenalkan skrip kelewatan di kepala, di dalam badan dan di luar badan skrip dan skrip biasa, dan merekodkan status pelaksanaan setiap kod melalui rentetan global Mari kita lihat hasil pelaksanaan dalam setiap penyemak imbas:

IE7 IE9 IE10 CHROME 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> 
Saya adalah ketua skrip luaran Saya ialah skrip dalaman kepala

Saya ialah skrip luaran badan
Saya adalah skrip luaran bahagian bawah

Saya mengetuai skrip kelewatan luaran

Saya sedang menunda skrip dalaman

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>
Saya ialah skrip kelewatan luaran badan Saya adalah skrip kelewatan luaran bahagian bawah Saya ialah skrip dalam DOMContentLoaded Saya ialah skrip dalam window.onload
Saya adalah ketua skrip luaran Saya ialah skrip dalaman kepala Saya ialah skrip luaran badan Saya adalah skrip luaran bahagian bawah Saya mengetuai skrip kelewatan luaran Saya sedang menunda skrip dalaman Saya ialah skrip kelewatan luaran badan Saya adalah skrip kelewatan luaran bahagian bawah Saya ialah skrip dalam DOMContentLoaded Saya ialah skrip dalam window.onload Saya adalah ketua skrip luaran Skrip dalaman saya tertunda Saya ialah skrip dalaman kepala Saya ialah skrip luaran badan Saya adalah skrip luaran bahagian bawah Saya mengetuai skrip kelewatan luaran Saya ialah skrip kelewatan luaran badan Saya adalah skrip kelewatan luaran bahagian bawah Saya ialah skrip dalam DOMContentLoaded Saya ialah skrip dalam window.onload Saya adalah ketua skrip luaran Skrip dalaman saya tertunda Saya ialah skrip dalaman kepala Saya ialah skrip luaran badan Saya adalah skrip luaran bahagian bawah Saya mengetuai skrip kelewatan luaran Saya ialah skrip kelewatan luaran badan Saya adalah skrip kelewatan luaran bahagian bawah Saya ialah skrip dalam DOMContentLoaded Saya ialah skrip dalam 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个脚本,然而在IEe38fbe55cac2ce5ddb0cc9a0db21efee définit à la fois les attributs defer et async, il sera traité comme asynchrone (remarque : les navigateurs qui ne prennent pas en charge async ignoreront directement l'attribut async)

[2] Si l'élément 3f1c4e4b6b16bbbd69b2ee476dc4f83a définit uniquement defer, il sera traité comme un script retardé

[3] Si l'élément 3f1c4e4b6b16bbbd69b2ee476dc4f83a ne définit pas defer ou async, il sera traité normalement, c'est-à-dire : le script sera chargé et exécuté immédiatement

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn