標籤:

我理解的同步載入與非同步載入

寫在前面:本文為本人的學習筆記,供自己複習參考,順便記錄自己成長過程,出錯的地方還請不吝賜教,另:本人平時學習搜索一些前輩的博客參考,故本文如有雷同,請留言,我立即刪除.

在說這兩種載入方式之前,我認為需要先說說瀏覽器的渲染機制。

首先,瀏覽器渲染頁面的時候通常是按照以下四個步驟依次來進行的:

  1. 瀏覽器解析HTML標籤,構建DOM樹。(DOM樹即為Document Object Model 文檔對象模型,之所以稱之為DOM樹是因為整個文檔對象有非常複雜的父子關係,與樹形結構相似。)
  2. 瀏覽器解析css,構建CSSOM樹。(CSSOM樹即為CSS Object Model,與DOM樹類似)
  3. 有了DOM樹描述文檔的結構與內容,CSSOM樹描述相應的樣式規則之後,瀏覽器將DOM樹和CSSOM樹結合在一起,形成render tree(渲染樹)
  4. 瀏覽器得到渲染樹之後,開始計算每個節點的位置信息,也就是開始布局。
  5. 布局完成之後,瀏覽器開始將每個節點繪製在屏幕上(painting過程)

這裡有兩點需要注意:

  1. 在瀏覽器解析HTML的時候,遇到script標籤立即開始載入javaScript並執行,這個過程會阻塞後面內容的呈現,也就是說會是後面的標籤在javaScript執行完成後才呈現,同時也會阻塞後面組件的載入,也就是說script標籤後面的組件如圖片等在javaScript執行完成後才開始載入,這就是我們說的同步載入,顯然我們在頁面上使用javaScript的時候,如果位置放置不當,將嚴重影響瀏覽器渲染的效率,所以我們一般把javaScript放在頁面的最底部,避免瀏覽器在解析javaScript的時候出現資源阻塞。如果把script標籤放在頁面的首部且javaScript文件載入需要花很長的時間的話,頁面會出現較長時間的白屏。
  2. 在瀏覽器解析HTML的時候,如果遇到<link rel="stylesheet" href="style.css">標籤的時候,向伺服器放出請求來獲得css文件,與此同時瀏覽器繼續往下解析HTML文件,構建DOM樹,這就是我們說的非同步載入,這裡我們可以看到,載入css文件的是時候,瀏覽器仍可以繼續做其他的工作,所以我們一般在頁面的首部就引入css文件。那麼如果css文件較大,DOM樹已經構建完成很久,CSSOM還沒有構建完成會出現什麼情況呢?不同的瀏覽器有不同的做法,比如chrome認為,樣式都沒有,painting是沒有意義的,於是chrome會出現白屏,直到CSSOM構建完成;firefox觀點與chrome不同,firefox認為還是給用戶看點東西吧,就算樣式還沒載入好,要不人家用戶以為咱瀏覽器出現問題了把咱給卸載了咋辦,於是firefox會先給用戶看點東西,等到CSSOM載入好了又突然把樣式給加上了,嚇用戶一跳,這就是我們說的無樣式內容閃爍。
  3. 上面說javaScript是同步載入的不怎麼好,css是非同步載入的甚合我意,那麼咱能不能把javaScript也給弄成非同步載入的呢?不僅能,而且有兩種方式:
    1. 給script加上defer屬性:

      <script defer src="script.js" ></script>

      有了defer屬性之後,載入和渲染後續文檔的過程將與script.js的載入一起進行,實現了javaScript與後續文檔的非同步載入,但script.js要在所有元素解析完成之後才開始執行.
    2. 給script加上async屬性:

      <script async src="script.js" ></script>

      有了async屬性之後,載入和渲染後續文檔的過程將與script.js的載入和執行同時進行,這也實現了javaScript與後續文檔的非同步載入,但async屬性不能保證順序,因為script.js載入好了就直接開始執行.

如有問題,歡迎指導,我的郵箱:xiesongwu55@outlook.com

推薦閱讀:

從process.versions了解Node.js的構成
低仿vue-async-computed
Typescript玩轉設計模式 之 對象行為型模式(上)
web前端:如何(安全地)使用Vue.js的jQuery插件
從Chrome源碼看HTTP

TAG:前端開發 |