瀏覽器頁面加載解析渲染機制(一)

一:爲何要了解瀏覽器渲染頁面和加載頁面機制,主要仍是性能的優化。javascript

  • 瞭解瀏覽器如何進行加載,咱們能夠在引用外部樣式文件,外部js時,將他們放到合適的位置,使瀏覽器以最快的速度將文件加載完畢。
  • 瞭解瀏覽器如何進行解析,咱們能夠在構建DOM結構,組織css選擇器時,選擇最優的寫法,提升瀏覽器的解析速率。
  • 瞭解瀏覽器如何進行渲染,明白渲染的過程,咱們在設置元素屬性,編寫js文件時,能夠減小」重繪「」從新佈局「的消耗。

  這三個過程在實際進行的時候又不是徹底獨立,而是會有交叉。會形成一邊加載,一邊解析,一邊渲染的工做現象。css

二:用戶訪問網頁都發生了什麼。html

  1. 用戶訪問網頁,DNS服務器(域名解析系統)會根據用戶提供的域名查找對應的IP地址,找到後,系統會向對應IP地址的網絡服務器發送一個http請求。
  2. 網絡服務器解析請求,併發送請求給數據庫服務器。
  3. 數據庫服務器將請求的資源返回給網絡服務器,網絡服務器解析數據,並生成html文件,放入http response中,返回給瀏覽器。
  4. 瀏覽器解析 http response。
  5. 瀏覽器解析 http response後,須要下載html文件,以及html文件內包含的外部引用文件,及文件內涉及的圖片或者多媒體文件。(這裏進入主題了也就是下面的第三大點)

  1~4步驟HTTP協議的一些內容,訪問服務器端可能遭遇的問題:若是網絡服務器沒法獲取數據庫服務器返回的資源文件(http response 404),或者因爲併發緣由暫時沒法處理用戶的http請求(http response 500)。java

三:瀏覽器渲染頁面和解析加載頁面機制。數據庫

  a.加載,即爲獲取資源文件的過程,不一樣瀏覽器,以及他們的不一樣版本在實現這一過程時,會有不一樣的實現效果(資源間互相阻塞,能夠用timeline來作測試)。這裏先說下瀏覽器的5個常駐線程:瀏覽器

  1. 瀏覽器GUI渲染線程
  2. javascript引擎線程
  3. 瀏覽器定時器觸發線程(setTimeout)
  4. 瀏覽器事件觸發線程
  5. 瀏覽器http異步請求線程(.jpg <link />這類請求)

  備註:現代瀏覽器存在 prefetch 優化,瀏覽器會另外開啓線程,提早下載js、css文件,須要注意的是,預加載js並不會改變dom結構,他將這個工做留給主加載。服務器

  注意:這裏也涉及到 阻塞 的現象,當js引擎線程(第二個)進行時,會掛起其餘一切線程,這個時候三、四、5這三類線程也會產生不一樣的異步事件,因爲 javascript引擎線程爲單線程,因此代碼都是先壓到隊列,採用先進先出的方式運行,事件處理函數,timer函數也會壓在隊列中,不斷的從隊頭取出事件,這就叫:javascript-event-loop。簡單點說應該是當在進行第二線程的時候,1,3,4,5都會掛起,好比這時候觸發click事件,即便先前JS已經加載完成,click事件會壓在隊列裏,這裏也要先完成第二線程纔會執行click事件。網絡

  加載順序:併發

  1. 瀏覽器解析http response 下載html文件會」自上而下「加載,並在加載過程當中進行解析渲染。「自上而下」加載時遇到圖片、視頻之類資源時便會進入第5個線程,這是異步請求,並不會影響html文檔進行加載。
  2. 加載過程當中遇到外部css文件,瀏覽器另外發出一個請求,來獲取css文件。這裏也是第5個線程,這裏css解析會生成一個rule tree(規則樹),這個之後會更新。
  3. 當文檔加載過程當中遇到js文件,html文檔會掛起渲染(加載解析渲染同步)的線程,不只要等待文檔中js文件加載完畢,還要等待解析執行完畢,才能夠恢復html文檔的渲染線程。

  緣由:JS有可能會修改DOM,最爲經典的document.write,這意味着,在JS執行完成前,後續全部資源的下載多是沒有必要的,這是js阻塞後續資源下載的根本緣由。
  辦法:能夠將外部引用的js文件放在</body>前。dom

  4. css可能影響js的執行形成阻塞。

  緣由:如js裏面var width = $('#id').width();這裏js執行前,瀏覽器必須保證以前的css文件已下載和解析完成(後面的不會影響),這也是css阻塞後續js的根本緣由。當js文件不須要依賴css文件時,能夠將js文件放在頭部css的前面。

  5. 預加載網頁,利用空餘時間來提早加載該網頁的後續網頁。

<link rel="prefetch" href="http://">

  6. 爲js腳本添加defer屬性,其不會阻塞後續DOM的的渲染。可是由於這個defer只是IE專用,因此通常用得比較少。而咱們標準的的HTML5也加入了一個異步載入javascript的屬性:async,不管你對它賦什麼樣的值,只要它出現,它就開始異步加載js文件。可是, async的異步加載會有一個比較嚴重的問題,那就是它忠實地踐行着「載入後立刻執行」這條軍規,因此,雖然它並不阻塞頁面的渲染,可是你也沒法控制他執行的次序和時機。

<script defer="true" src="JavaScript.js" type="text/javascript"/>

  mark--zhq[2]。

 

相關文章
相關標籤/搜索