前端效能優化(一)——瀏覽器工作原理
阿新 • • 發佈:2021-08-30
作為一個前端,經常會有老闆或測試給我們提出某個地方載入太慢了,需要優化一下。我們自己的網站也一樣,載入時間過長,自己都不耐煩,對於網頁優化是很常見的,今天我們先介紹下網頁載入原理。
一、瀏覽器簡介
想要了解瀏覽器的工作原理,我們必須清楚瀏覽器的組成有哪些?以及各個部分功能。
瀏覽器組成部分如圖所示:
各部分的功能及意義:
- 使用者介面:瀏覽器的介面,有標籤頁、位址列、前進、後退、重新整理、收藏等。除了請求到的內容頁面。
- 瀏覽器引擎:用來查詢和操作渲染引擎的介面。
- 渲染引擎:也叫做 “瀏覽器核心” ,用來解析 html、css 並將結果以網頁的形式顯示,不同瀏覽器核心不同,同理渲染引擎也不同。
- 網路:用來網路呼叫,如前後端資料互動中的http請求。
- js 直譯器:用來解釋執行js程式碼。
- UI 後端:繪製基礎原件,如組合框與視窗,提供平臺無關的介面,內部使用作業系統的相應實現。
- 資料儲存:屬於持久層。瀏覽器需要把所有資料存到硬碟上,如 cookie、圖片、css 等。
二、瀏覽器工作流程
我們在瀏覽器使用者介面的位址列中,輸入我們需要訪問網站地址url後回車。
瀏覽器工作流程:
- 構建請求:瀏覽器開啟網路請求執行緒,向伺服器傳送完整的http請求。
- 查詢快取:真正發起網路請求之前,瀏覽器會先在資料儲存中查詢是否有需要請求的檔案。如果沒有任何快取,說明第一次請求,則進入網路請求過程。當瀏覽器有快取的時候,會攔截請求,返回快取,攔截請求。快取優點:緩解伺服器壓力,提升效能,實現快速載入資源。
- 準備IP地址和埠:通過 URL 地址獲取 ip 地址和埠資訊,通過 DNS 解析返回域名對應的 ip 和 port ,瀏覽器也提供了 dns 資料快取,通常 url 沒有指明埠號,則預設80。
- 等待TCP佇列:chrome 有個機制,同一域名下同時最多隻能建立6個TCP連線,如果同時有10個請求發生,其中4個就會進入等待佇列,直至進行中的請求完成,如果小於6個,則直接進入TCP 連線。
- 建立TCP連線:瀏覽器與伺服器之間通過 TCP 建立連線。TCP協議提供可靠的連線服務,採用三次握手建立一個連線。
- 傳送http請求:連線建立成功之後,瀏覽器就可以與伺服器之間通訊了。瀏覽器會向伺服器傳送請求資訊,包括請求方法、請求 URL、http 版本協議。
- 伺服器處理請求:服務端收到請求資訊以後,會根據瀏覽器的請求資訊返回結果,返回結果中包含三部分:響應行、響應頭、響應體。響應行內包含狀態碼,告訴瀏覽器處理結果,http狀態碼有很多。響應頭包含伺服器自身的一些資訊,響應體就包含了網頁的 html 實際內容。
- 伺服器響應和斷開連線:通常伺服器向瀏覽器返回請求資料之後,就會關閉連線,經過四次分手之後,就斷開連線了。
瀏覽器中http請求階段如圖:
http請求和響應處理,是前端與後端資料互動的時候經常使用的部分。
三、瀏覽器渲染過程
渲染引擎通過網路獲得請求文件內容(以8k分塊的方式完成),然後開始:解析html為DOM樹 > 渲染樹結構 > 佈局渲染 > 繪製渲染樹。
具體解析過程為:
開始解析 html 內容,將標籤轉化為 DOM 節點,然後解析它外部的css檔案以及 style 中的樣式資訊。css 樣式資訊和 html 標籤來構建渲染樹。渲染樹是由一些包含顏色大小等盒子組成的,按照從上到下,從左到右的方式顯示,渲染樹構建好之後,執行佈局過程,將每個節點確定在螢幕上的確切座標,最後使用 UI 後端層繪製每個節點。
舉例說明下瀏覽去解析 html、css、js 的過程:
- 瀏覽去位址列輸入地址後回車,假設第一次訪問,瀏覽去向伺服器傳送請求,返回html檔案。
- 瀏覽去載入html程式碼,解析head中的link引入的外部css檔案。
- 瀏覽器發出css檔案請求,伺服器會返回css檔案。
- 瀏覽器繼續載入body部分程式碼,css檔案接收到之後,就可以渲染頁面。
- 遇到img標籤引入圖片,會立馬向伺服器傳送請求,此時不等待返回的圖片,而是繼續向下渲染。
- 瀏覽器接收到返回圖片檔案,由於圖片佔用一定面積,影響後邊排版,所以瀏覽去需要回過頭重新渲染這部分程式碼。
- 瀏覽器發現script標籤,內部包含的js程式碼,就會立即執行。
- js指令碼執行js語句,如果js語句操作的是DOM元素,瀏覽器就需要重新渲染這部分程式碼。
- 等到</html>到來,頁面第一次渲染就完成了。
- 如果使用者點選"換膚"按鈕,js讓瀏覽器換一個css檔案,此時瀏覽去又會向伺服器傳送請求。
- 等瀏覽器返回新的css檔案之後,重新渲染頁面。
需要注意:
- js不能並行下載和解析(阻塞下載)。
- 當引用了JS的時候,瀏覽器傳送1個js request就會一直等待該request的返回。因為瀏覽器需要1個穩定的DOM樹結構,而JS中很有可能有程式碼直接改變了DOM樹結構,比如使用 document.write 或 appendChild,甚至是直接使用的location.href進行跳轉,瀏覽器為了防止出現JS修改DOM樹,需要重新構建DOM樹的情況,所以 就會阻塞其他的下載和呈現。
- JS、CSS中如有重定義,後定義函式將覆蓋前定義函式。
先了解網頁的請求,載入,解析過程,然後再考慮到底該如何優化網頁效能呢?