Rumah >hujung hadapan web >tutorial js >Kesan JS, CSS dan img pada kemahiran DOMContentLoaded event_javascript
前端的纯技术就是对规范的认知
什么是DOMContentLoaded事件?
首先想到的是查看W3C的HTML5规范,DOMContentLoaded事件在什么时候触发:
Setelah ejen pengguna berhenti menghuraikan dokumen, ejen pengguna mesti menjalankan langkah berikut:
1. Tetapkan kesediaan dokumen semasa kepada "interaktif" dan titik sisipan kepada tidak ditentukan.
Keluarkan semua nod daripada timbunan elemen terbuka.
2. Jika senarai skrip yang akan dilaksanakan apabila dokumen selesai menghurai tidak kosong, jalankan sublangkah ini:
2.1 Putar gelung acara sehingga skrip pertama dalam senarai skrip yang akan dilaksanakan apabila dokumen selesai menghurai mempunyai bendera "sedia untuk dihuraikan" ditetapkan dan Dokumen penghurai tidak mempunyai helaian gaya yang menyekat skrip.
2.2 Laksanakan skrip pertama dalam senarai skrip yang akan dilaksanakan apabila dokumen telah selesai dihuraikan.
2.3 Alih keluar elemen skrip pertama daripada senarai skrip yang akan dilaksanakan apabila dokumen telah selesai menghurai (iaitu alih keluar masukan pertama dalam senarai).
2.4 Jika senarai skrip yang akan dilaksanakan apabila dokumen telah selesai menghurai masih tidak kosong, ulangi sublangkah ini sekali lagi daripada sublangkah 1.
3. Baris gilir tugas untuk melancarkan acara mudah yang berbuih bernama DOMContentLoaded di Dokumen.
规范总是那么的晦涩,但至少有一点是可以明确了的,就是在JS(不包怬有一点是可以明确了的,就是在JS(不包怬有一点是可以明确了的,就是在JS(不包怬有不包怬匨是之后,才会触发DOMContentLoaded事件。
接下来看看MDN上有关DOMContentLoaded事件的文档:
Acara DOMContentLoaded dicetuskan apabila dokumen telah dimuatkan dan dihuraikan sepenuhnya, tanpa menunggu lembaran gaya, imej dan subbingkai selesai dimuatkan
Nota: Stylesheet memuatkan pelaksanaan skrip blok, jadi jika anda mempunyai<font face="NSimsun"><script></script></font>
selepas<font face="NSimsun"><link rel="stylesheet" ...></font>
, halaman tidak akan selesai menghurai – dan DOMContentLoaded tidak akan menyala – sehingga helaian gaya dimuatkan.
这么看来,至少可以得出这么一个理论:DOMContentLoaded事件本身不会等待CSS文件i片家图片中文。 🎜>
它的触发时机是:加载完页面,解析完所有标签(不包括执行CSS和JS),并倂佐完所有标签(不包括执行CSS和JS),并倂佐約色和执行每个静态的script标签中的JS,然后触发。
而JS的执行,需要等待位于它前面的CSS加载(如果是外联的话)、执行完成,S你为住它前面的CSS计算出来的样式。<font face="NSimsun">interactive</font>
实践是检验真理的唯一标准
实验1:DOMContentLoaded事件不直接等待CSS文件、图片的加载完成
index.html:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title></title> <link rel="stylesheet" type="text/css" href="./css/main.css" rel="external nofollow" rel="external nofollow" > </head> <body> <p>Content</p> <img src="./img/chrome-girl.jpg" alt="Kesan JS, CSS dan img pada kemahiran DOMContentLoaded event_javascript" > </body> </html>
如果页面中没有script标签,DOMContentLoaded事件并没有等待CSS文件、图片加载完成>。Chrome开发者工具的Timeline面板可以帮我们记录下浏览器的一举一动。图一中红色的图一中红色ContentLoaded事件,它右边的红线和绿线分别表示load事件和Pertama melukis吧!)。
实验2:DOMContentLoaded事件需要等待JS执行完才触发
index.html:
main.js:
console.timeStamp('External script after link in body');
图二
如果页面中静态的写有script标签,DOMContentLoaded事件需要等待JS执行完才触发。
而script标签中的JS需要等待位于其前面的CSS的加载完成。
console.timeStamp() 可以向Timeline中添加一条记录,并对应上方的一条黄线。
从图二中可以看出,在CSS之前的JS立刻得到了执行,而在CSS之后的JS,需要等待CSS加载完后才执行,比较明显的是main.js早就加载完了,但还是要等main.css加载完才能执行。而DOMContentLoaded事件,则是在JS执行完后才触发。滑动Timeline面板中表示展示区域的滑块,如图三,放大后即可看到表示DOMContentLoaded事件的蓝线(之前跟黄线和绿线靠的太近了),当然,通过 console.timeStamp() 向TimeLine中添加的记录也可证明其触发时间。
图三
现代浏览器会并发的预加载CSS, JS,也就是一开始就并发的请求这些资源,但是,执行CSS和JS的顺序还是按原来的依赖顺序(JS的执行要等待位于其前面的CSS和JS加载、执行完)。先加载完成的资源,如果其依赖还没加载、执行完,就只能等着。
实验3:img何时开始解码、绘制?
从图三中我们可以发现一个有趣的地方:img的请求老早就发出了,但延迟了一段时间才开始解码。如图二、图三中的红框所示,截图中只框出了一部分表示解码的记录,而实际上这些表示解码的记录一直持续到img加载结束,如图四所示,img是一边加载一边解码的:
图三
现代浏览器会并发的预加载CSS, JS,也就是一开始就并发的请求这些资源,但是,执行CSS和JS的顺序还是按原来的依赖顺序(JS的执行要等待位于其前面的CSS和JS加载、执行完)。先加载完成的资源,如果其依赖还没加载、执行完,就只能等着。
实验3:img何时开始解码、绘制?
从图三中我们可以发现一个有趣的地方:img的请求老早就发出了,但延迟了一段时间才开始解码。如图二、图三中的红框所示,截图中只框出了一部分表示解码的记录,而实际上这些表示解码的记录一直持续到img加载结束,如图四所示,img是一边加载一边解码的:
抱着“猜想——验证”的想法,我猜想这是因为img这个资源是否需要展现出来,需要等 所有的JS和CSS的执行完 才知道,因为main.js可能会执行某些DOM操作,比如删除这个img元素,或者修改其src属性,而CSS可能会将其 <font face="NSimsun">display: none</font>
。
图五中没有JS和CSS,img的数据一接收到就马上开始解码了。
图六中没有JS,但img要等到CSS加载完才开始解码。
图七的代码跟图六的代码唯一的区别是CSS把img给 <font face="NSimsun">display: none;</font>
,这使得img虽然请求了,但根本没有进行解码。
这说明,img是否需要解码、绘图(paint)出来,确实需要等CSS加载、执行完才能知道。也就是说,CSS会阻塞img的展现!那么JS呢?
图八对应的代码:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> console.timeStamp('Inline script in head'); window.addEventListener('DOMContentLoaded', function(){ console.timeStamp('DOMContentLoaded event'); }); </script> </head> <body> <p>Content</p> <img src="./img/chrome-girl.jpg" alt="Kesan JS, CSS dan img pada kemahiran DOMContentLoaded event_javascript" > <script type="text/javascript" src="./js/main.js"></script> </body> </html>
Sangat mengejutkan bahawa dalam halaman dengan JS tetapi tiada CSS, img sebenarnya boleh mula menyahkod dan melukis (mengecat) sejurus selepas menerima data, dengan kata lain, JS tidak menyekat paparan img! Ini berbeza daripada pemahaman kami sebelum ini tentang konsep tradisional bahawa JS akan menyekat sumber img Nampaknya Chrome telah membuat pengoptimuman baharu untuk pemuatan dan paparan img.
Kaedah $(document).ready() yang biasa kami gunakan dalam jQuery adalah untuk memantau acara DOMContentLoaded (sudah tentu, ia juga menyediakan penyelesaian turun taraf secara dalaman dengan mensimulasikan acara DOMContentLoaded dan memantau acara onload). Biasanya disyorkan untuk mendaftarkan acara untuk elemen DOM apabila acara DOMContentLoaded dicetuskan. Jadi mencetuskan acara DOMContentLoaded secepat mungkin bermakna halaman itu boleh dibuat interaktif secepat mungkin:
Kurangkan saiz fail CSS, bahagikan satu fail CSS kepada beberapa fail untuk pemuatan selari dan kurangkan masa penyekatan CSS pada JS
Fail JS kedua dimuatkan dengan memasukkan teg skrip secara dinamik (teg skrip yang dimasukkan secara dinamik tidak menyekat pencetus peristiwa DOMContentLoaded)
Sprite yang digunakan dalam CSS boleh dimuatkan bersama-sama dengan fail CSS dalam HTML dengan pramuat img
Semasa percubaan, saya merasakan bahawa panel Garis Masa alat pembangun Chrome sangat berkuasa dan setiap pergerakan penyemak imbas telah direkodkan. Pada masa lalu, jika kami ingin memahami dan meneroka gelagat dalaman penyemak imbas dalam pembangunan bahagian hadapan, kami sama ada akan melakukan ujian kotak hitam dengan merasakan batu, atau mengkaji kod sumber penyemak imbas dengan dua kali ganda hasil dan separuh usaha. Satu-satunya cara yang berkesan ialah belajar daripada pengalaman penyelidikan orang lain dan melihat artikel pengalaman penyelidikan orang asing, tetapi perkembangan penyemak imbas berubah setiap hari (contohnya, JS yang terdapat dalam eksperimen ini tidak menyekat paparan img. ), pengalaman orang lain bukanlah yang terkini dan paling sesuai Kuncinya adalah untuk menggabungkan perniagaan anda sendiri dan senario permintaan, dan membuat keputusan yang disasarkan Analisis dan pengoptimuman.
PS.
Persekitaran ujian di atas ialah windows/chrome dan Fiddler digunakan untuk mensimulasikan rangkaian perlahan