HTML加載過程

HTML加載流程圖

在地址欄輸入url,返回html後,瀏覽器開始順序加載並渲染DOMcss

Body標籤

當瀏覽器遇到body標籤纔算真正開始加載並渲染DOM,此時會有如下幾種狀況:html

DOM元素

瀏覽器遇到dom元素時,正常順序加載,邊加載邊渲染bootstrap

內聯CSS

當遇到內聯CSS時,瀏覽器繼續加載,但渲染被阻塞,此時會生成新的CSS Rule Tree,生成後從新渲染界面瀏覽器

外聯CSS

當遇到外聯CSS(link標籤),瀏覽器啓一個線程加載css文件,DOM繼續加載但渲染被阻塞dom

內聯Javascript

當遇到內聯Javascript,瀏覽器開始執行這段腳本,DOM的加載和渲染同時被阻塞(因爲JavaScript有可能會更改DOM Tree和Render Tree,所以同時被阻塞)async

外聯Javascript

當遇到外聯Javascript,瀏覽器開始下載這段腳本,下載成功後執行它,這整個過程DOM的加載和渲染同時被阻塞url

Example

用一個例子解釋一下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加載設計

defer 與 async

若是咱們執行如下代碼,首先加載外部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

相關文章
相關標籤/搜索