1. HTML 頁面組成
- 一個 HTML 頁面是由很多資原始檔組成的
- 比如最基本的 HTML 本身是一個資源
- css、js 這些靜態資源
- 圖片、文字、json 介面等資源
- 這些資源一般通過
http/https
請求,從伺服器
上拿過來
2. 資源載入過程
- 第一步,
對於一個請求來說
,無論是位址列輸入的 url
,還是程式碼中載入的 url
,都要對 url 進行解析
,提取資訊
- 第二步,拿到上一步中
解析的域名
,去 DNS 伺服器上查詢該域名對應的 IP
- 第三步,
帶著所有的請求資訊去這個 IP 地址上請求資源
,然後在伺服器上把返回的資源下載下來
- 最後一步,瀏覽器拿到這些資源之後,
根據不同的資源型別做不同方式的解析
2.1 URL 解析
請求協議
域名+埠
- 域名用來
查詢伺服器位置
- 域名就像一個大房子,有一個
IP 地址
- 等找到這個房子的地址後,
埠
就是這個房子的門 - 一般的協議還有一個
預設的埠號
- 比如 http 協議預設的埠號是 80
- 比如 https 協議預設的埠號是 443
如果訪問的是預設埠的話,這個埠號是可以省略的
路徑
- 這個路徑是
伺服器接到請求以後,拿著這個路徑在伺服器上定位資源位置的
引數
雜湊
2.2 DNS 查詢
DNS 域名系統(Domain Name System)
2.2.1 DNS 查詢過程
當一個 URL 地址被解析以後,拿到一個域名,但是在網際網路上,資源都是用 IP 地址來訪問的,沒域名什麼事
- 所以
需要把域名轉化成 IP 地址
- 在 DNS 裡有兩個端
- 如果所有使用者的每一次請求都去查一下 DNS 伺服器,這個量級是異常巨大的
- 所以在 DNS 裡有一個很重要的部分,就是
DNS 快取
,用來減少 DNS 伺服器上的查詢量
在做 DNS 查詢時,瀏覽器會傳遞一個要解析的域名
- 比如 www.happymmall.com
傳給 DNS 系統
經過 DNS 查詢,這個域名會對應一個 IP 地址
- 比如是 97.65.113.212,這就是 www.happymmall.com 的
伺服器地址
2.2.2 DNS 查詢場景
場景
- 小明去新華書店買書,不知道路線
- 去問張大爺,張大爺也不知道,查詢了地址簿,告訴了小明(
相當於 DNS 查詢
) - 不一會,小紅也去新華書店,也不知道路線,也去問張大爺,張大爺
直接
告訴小紅地址(相當於 DNS 快取
) - 過了一個月,小花也去新華書店,也不知道路線,也去問張大爺,張大爺忘了地址,再去地址簿上查詢,然後告訴小花(
這一個月相當於 DNS 快取時間,過期就忘了
)
2.2.3 DNS 快取
- DNS 快取並不是一個,而是有很多層
根據不同的網路層級,DNS 快取時間也不一樣
- 一般
越靠近使用者的節點,快取時間越短
- 比如離使用者最近的
瀏覽器
,一般快取時間是1分鐘或者30秒
DNS 根伺服器上的快取時間一般能達到10分鐘
2.2.4 dns-prefetch
<link rel="dns-prefetch" href="//cdn.bootcss.com">
<link rel="dns-prefetch" href="//s.happymmall.com">
<link rel="dns-prefetch" href="//img.happymmall.com">
dns-prefetch 原理
在頁面一開始載入時,就會立即把這幾個 href 裡指定的域名做 DNS 查詢並快取起來
等到真正請求這些域名並下載資源的時候,就可以省去 DNS 查詢時間
可以提高頁面的載入速度
2.3 資源請求
2.3.1 資原始檔
- 這個資源可以是
HTML、CSS、JS、或者介面等資原始檔
可以通過 http 請求得來的任何內容
2.3.2 資源請求過程
- 資源請求有兩個角色
在發起請求時,瀏覽器會帶著一堆資訊,去後端伺服器上尋找資源
- 這個請求包含兩個部分
Request-header 請求頭
- 裡面包含了很多請求本身的資訊
- 我需要請求誰
- 我從哪裡來
- 我希望得到什麼格式的資料
- 我用的什麼瀏覽器
- cookie
請求帶的引數
- get 請求,引數在 url 裡
- post 請求,引數在請求的 body 裡
當這些資訊到達伺服器後,伺服器會根據這些到達的資訊,找到匹配的資源,返回給瀏覽器
- 返回的資訊包括三部分
狀態碼
,表示請求結果是否成功Response-header 響應頭
,包含響應資訊(文字長度、快取時間、壓縮方式等)響應內容
- 如果是圖片,返回的 body 裡就是圖片資訊
- 如果是介面,返回的 body 裡就是 json 字串
瀏覽器拿到這些響應資訊後,就拿到了自己想要的東西
2.4 瀏覽器解析
2.4.1 DOM 樹
- 最先載入的是一個 HTML 檔案
在載入 HTML 檔案時,就已經開始構建 DOM 樹
- 遇到一個 HTML 節點就把它放到 DOM 樹裡
加入在載入一個 HTML 檔案的時候遇到了一個 JS 檔案
- 那麼構建 DOM 樹的工作就要停下來,
先讓 JS 檔案載入和執行
JS 檔案有這麼高的優先順序,是因為 JS 檔案能操作 DOM 樹,可能造成之前的 DOM 樹白乾,所以在遇到 JS 檔案的時候,先讓 JS 檔案執行,等 JS 檔案執行完,在接著走
- JS 檔案執行完後,又構建之前剩下的 DOM 樹
構建 DOM 樹的過程中,如果遇到的是 style 標籤,不會造成阻塞
DOM 樹的構建和樣式的載入會並行執行
- DOM 樹構建完後,就構建渲染樹
2.4.2 渲染樹
渲染樹,是 DOM 樹和樣式表結合的產物
這個渲染樹在各個瀏覽器裡構造的機制也不一樣
- 比如 Chrome 瀏覽器用的 webkit 核心是在原來的 DOM 樹上附屬一些樣式
- 而 firefix 裡是根據 DOM 樹和樣式表重新構建出一顆渲染樹出來
- 渲染樹構建好之後,每個要顯示的元素的大小、佈局方式也就確定了
2.4.3 佈局
- 接下來就是
根據每個元素的大小和佈局方式計算出每個元素的實際位置,這就是佈局的過程
2.4.4 繪製
- 最後一步繪製
- 上一步的佈局確定了元素的大小和位置
繪製過程就是呼叫瀏覽器負責顯示的部分,將元素和樣式繪製在對應的螢幕上
這樣整個瀏覽器的解析過程就完成了
3. 總結
- 當輸入一個 URL 會發生什麼?
- 面試問到了,答得不好,記錄一下