HTML加載流程圖
在地址欄輸入url,返回html后,瀏覽器開始順序加載并渲染DOM
Body標簽
當瀏覽器遇到body標簽才算真正開始加載并渲染DOM掂咒,此時會有以下幾種情況:
DOM元素
瀏覽器遇到dom元素時,正常順序加載迈喉,邊加載邊渲染
內(nèi)聯(lián)CSS
當遇到內(nèi)聯(lián)CSS時绍刮,瀏覽器繼續(xù)加載,但渲染被阻塞挨摸,此時會生成新的CSS Rule Tree孩革,生成后重新渲染界面
外聯(lián)CSS
當遇到外聯(lián)CSS(link標簽),瀏覽器啟一個線程加載css文件得运,DOM繼續(xù)加載但渲染被阻塞
內(nèi)聯(lián)Javascript
當遇到內(nèi)聯(lián)Javascript膝蜈,瀏覽器開始執(zhí)行這段腳本,DOM的加載和渲染同時被阻塞(由于JavaScript有可能會更改DOM Tree和Render Tree熔掺,因此同時被阻塞)
外聯(lián)Javascript
當遇到外聯(lián)Javascript饱搏,瀏覽器開始下載這段腳本,下載成功后執(zhí)行它置逻,這整個過程DOM的加載和渲染同時被阻塞
Example
用一個例子解釋一下
<html>
<body>
<h2>Hello</h2>
<script>
function print(){
console.log('first script', document.querySelectorAll('h2'));
}
print();
setTimeout(print);
</script>
<script src="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.4/js/bootstrap.js"></script>
<h2>World</h2>
<script> console.log('second script', document.querySelectorAll('h2')); </script>
</body>
</html>
在js文件下載的過程中推沸,js后面的元素沒有被加載,也沒有呈現(xiàn)在界面上券坞,說明js文件的下載阻塞了DOM的解析并渲染
<html>
<body>
<h2>Hello</h2>
<script>
function print(){
console.log('first script', document.querySelectorAll('h2'));
}
print();
setTimeout(print);
</script>
<link rel="stylesheet" >
<h2>World</h2>
<script> console.log('second script', document.querySelectorAll('h2')); </script>
</body>
</html>
在css文件仍在下載的過程中鬓催,已經(jīng)可以打印出兩個<h>,可以看出css文件的加載阻塞了DOM渲染但沒有阻塞DOM加載
defer 與 async
如果我們執(zhí)行以下代碼恨锚,首先加載外部Javascript文件宇驾,然后加載DOM其他內(nèi)容:
<html>
<body>
<script src="https://cdn.bootcss.com/docsearch.js/2.5.2/docsearch.min.js"></script>
<h2>Hello World</h2>
</body>
</html>
如我們所料,文件沒有下載并執(zhí)行完畢猴伶,Hello World是不會打印出來的课舍。
如果我們?yōu)橥獠縅avascript添加defer或async屬性,那么它的下載就不會阻塞DOM其他內(nèi)容的加載:
<html>
<body>
<script async src="https://cdn.bootcss.com/docsearch.js/2.5.2/docsearch.min.js"></script>
<h2>Hello World</h2>
</body>
</html>
關(guān)于defer與async屬性的區(qū)別他挎,請參考我的另一篇文章:
Javascript高級程序設(shè)計讀書筆記——在HTML中使用Javascript