在地址欄輸入url,返回html後,瀏覽器開始順序加載並渲染DOMcss
當瀏覽器遇到body標籤纔算真正開始加載並渲染DOM,此時會有如下幾種狀況:html
瀏覽器遇到dom元素時,正常順序加載,邊加載邊渲染bootstrap
當遇到內聯CSS時,瀏覽器繼續加載,但渲染被阻塞,此時會生成新的CSS Rule Tree,生成後從新渲染界面瀏覽器
當遇到外聯CSS(link標籤),瀏覽器啓一個線程加載css文件,DOM繼續加載但渲染被阻塞dom
當遇到內聯Javascript,瀏覽器開始執行這段腳本,DOM的加載和渲染同時被阻塞(因爲JavaScript有可能會更改DOM Tree和Render Tree,所以同時被阻塞)async
當遇到外聯Javascript,瀏覽器開始下載這段腳本,下載成功後執行它,這整個過程DOM的加載和渲染同時被阻塞url
用一個例子解釋一下spa
<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後面的元素沒有被加載,也沒有呈如今界面上,說明js文件的下載阻塞了DOM的解析並渲染線程
<html> <body> <h2>Hello</h2> <script> function print(){ console.log('first script', document.querySelectorAll('h2')); } print(); setTimeout(print); </script> <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.4/css/bootstrap.css"> <h2>World</h2> <script> console.log('second script', document.querySelectorAll('h2')); </script> </body> </html>
在css文件仍在下載的過程當中,已經能夠打印出兩個<h>,能夠看出css文件的加載阻塞了DOM渲染但沒有阻塞DOM加載設計
若是咱們執行如下代碼,首先加載外部Javascript文件,而後加載DOM其餘內容:
<html> <body> <script src="https://cdn.bootcss.com/docsearch.js/2.5.2/docsearch.min.js"></script> <h2>Hello World</h2> </body> </html>
如咱們所料,文件沒有下載並執行完畢,Hello World是不會打印出來的。
若是咱們爲外部Javascript添加defer或async屬性,那麼它的下載就不會阻塞DOM其餘內容的加載:
<html> <body> <script async src="https://cdn.bootcss.com/docsearch.js/2.5.2/docsearch.min.js"></script> <h2>Hello World</h2> </body> </html>
關於defer與async屬性的區別,請參考個人另外一篇文章:
Javascript高級程序設計讀書筆記——在HTML中使用Javascript