從輸入 url 到頁面渲染
發(fā)起網(wǎng)絡(luò)前
1 緩存階段
1.1 瀏覽器與服務(wù)器通信的方式為應(yīng)答模式
- 瀏覽器發(fā)起 HTTP 請(qǐng)求 – 服務(wù)器響應(yīng)該請(qǐng)求戳粒。那么瀏覽器第一次向服務(wù)器發(fā)起該請(qǐng)求后拿到請(qǐng)求結(jié)果,會(huì)根據(jù)響應(yīng)報(bào)文中 HTTP 頭的緩存標(biāo)識(shí),決定是否緩存結(jié)果梗顺,是則將請(qǐng)求結(jié)果和緩存標(biāo)識(shí)存入瀏覽器緩存中
- 瀏覽器每次發(fā)起請(qǐng)求舆乔,都會(huì)先在瀏覽器緩存中查找該請(qǐng)求的結(jié)果以及緩存標(biāo)識(shí)
- 瀏覽器每次拿到返回的請(qǐng)求結(jié)果都會(huì)將該結(jié)果和緩存標(biāo)識(shí)存入瀏覽器緩存中
1.2 強(qiáng)制緩存
- 當(dāng)瀏覽器向服務(wù)器發(fā)送請(qǐng)求的時(shí)候,服務(wù)器會(huì)將緩存規(guī)則放入 HTTP 響應(yīng)的報(bào)文的 HTTP 頭中和請(qǐng)求結(jié)果一起返回給瀏覽器,控制強(qiáng)制緩存的字段分別是 Expires 和 Cache-Control茎杂,其中 Cache-Conctrol 的優(yōu)先級(jí)比 Expires 高
- Cache-Control(public,private,no-cache,no-store,max-age)
- Expires,服務(wù)器返回該請(qǐng)求的結(jié)果緩存的到期時(shí)間
1.3 協(xié)商緩存
- 協(xié)商緩存就是強(qiáng)制緩存失效后,瀏覽器攜帶緩存標(biāo)識(shí)向服務(wù)器發(fā)起請(qǐng)求纫雁,由服務(wù)器根據(jù)緩存標(biāo)識(shí)決定是否使用緩存的過程
- 標(biāo)識(shí) (Etag / If-None-Match 優(yōu)先級(jí)高于 Last-Modified / If-Modified-Since)
1.4 緩存位置
- from memory cache 內(nèi)存中緩存煌往,可快速讀取,有時(shí)效性轧邪,一旦該進(jìn)程關(guān)閉刽脖,則該進(jìn)程的內(nèi)存則會(huì)清空
- from disk cache 硬盤中緩存,需要對(duì)該緩存存放的硬盤文件進(jìn)行 I/O 操作忌愚,然后重新解析該緩存內(nèi)容曲管,讀取復(fù)雜,速度比內(nèi)存緩存慢
- 讀取順序 memory –> disk
1.5 總結(jié)
強(qiáng)制緩存優(yōu)先于協(xié)商緩存進(jìn)行硕糊,若強(qiáng)制緩存(Expires 和 Cache-Control)生效則直接使用緩存院水,若不生效則進(jìn)行協(xié)商緩存(Last-Modified / If-Modified-Since 和 Etag / If-None-Match),協(xié)商緩存由服務(wù)器決定是否使用緩存简十,若協(xié)商緩存失效檬某,那么代表該請(qǐng)求的緩存失效,重新獲取請(qǐng)求結(jié)果勺远,再存入瀏覽器緩存中橙喘;生效則返回 304,繼續(xù)使用緩存
1.6 啟發(fā)式緩存
如果響應(yīng)中未顯示 Expires胶逢,Cache-Control:max-age 或 Cache-Control:s-maxage厅瞎,并且響應(yīng)中不包含其他有關(guān)緩存的限制,緩存可以使用啟發(fā)式方法計(jì)算新鮮度壽命初坠。通常會(huì)根據(jù)響應(yīng)頭中的 2 個(gè)時(shí)間字段 和簸,Date 減去 Last-Modified 值的 10% 作為緩存時(shí)間
2 瀏覽器準(zhǔn)備階段
2.1 瀏覽器進(jìn)程
- 瀏覽器進(jìn)程,除標(biāo)簽頁外的其他用戶界面碟刺,前進(jìn)锁保,后退,地址欄半沽,書簽爽柒,及與其他進(jìn)程合作,包括 UI 線程者填,網(wǎng)絡(luò)線程
- GPU 進(jìn)程浩村,整個(gè)瀏覽器界面的渲染
- 網(wǎng)絡(luò)進(jìn)程,負(fù)責(zé)發(fā)起接受網(wǎng)絡(luò)請(qǐng)求
- 渲染進(jìn)程占哟,控制顯示 tab 標(biāo)簽內(nèi)的所有內(nèi)容心墅,每個(gè) tab 一個(gè)進(jìn)程酿矢,一個(gè)主線程(main thread),多個(gè)工作線程(work thread)怎燥,一個(gè)合成器線程(compositor thread)瘫筐,多個(gè)柵格線程(raster thread)
- 插件進(jìn)程,控制網(wǎng)站使用的插件铐姚,如 flash
- 緩存進(jìn)程
2.2 UI 線程工作
- 捕捉輸入內(nèi)容關(guān)鍵字策肝,使用默認(rèn)搜索引擎對(duì)應(yīng)的 URL 去 DNS 查詢地址
3 DNS 查詢階段
- DNS 域名解析過程,將域名谦屑,例如http://www.baidu.com驳糯,解析為 IP 地址的過程
- 瀏覽器緩存,瀏覽器會(huì)緩存 DNS 記錄持續(xù)一定時(shí)間氢橙,不同的瀏覽器時(shí)間間隔不同,大約在 2-30 分鐘
- 系統(tǒng)緩存恬偷,系統(tǒng)緩存主要存在/etc/hosts 中
- ISP 緩存悍手,互聯(lián)網(wǎng)服務(wù)提供商,如電信袍患,聯(lián)通坦康,移動(dòng),ISP 提供了本地 DNS 服務(wù)器诡延,用于提供 DNS 緩存服務(wù)
- 判斷是否啟用轉(zhuǎn)發(fā)模式
- 如果未用轉(zhuǎn)發(fā)模式滞欠,本地 DNS 就把請(qǐng)求發(fā)至 13 臺(tái)根 DNS,根 DNS 服務(wù)器收到請(qǐng)求后會(huì)判斷這個(gè)域名(.com)是誰來授權(quán)管理肆良,并會(huì)返回一個(gè)負(fù)責(zé)該頂級(jí)域名服務(wù)器的一個(gè) IP筛璧。本地 DNS 服務(wù)器收到 IP 信息后,將會(huì)聯(lián)系負(fù)責(zé)'.com 域'的這臺(tái)服務(wù)器惹恃。這臺(tái)負(fù)責(zé)'.com 域'的服務(wù)器收到請(qǐng)求后夭谤,如果自己無法解析,它就會(huì)找一個(gè)管理'.com 域'的下一級(jí) DNS 服務(wù)器地址http://baidu.com給本地 DNS 服務(wù)器巫糙。當(dāng)本地 DNS 服務(wù)器收到這個(gè)地址后朗儒,就會(huì)找http://baidu.com域服務(wù)器,重復(fù)上面的動(dòng)作参淹,進(jìn)行查詢醉锄,直至找到http://www.baidu.com主機(jī)
- 如果用的是轉(zhuǎn)發(fā)模式,此 DNS 服務(wù)器就會(huì)把請(qǐng)求轉(zhuǎn)發(fā)至上一級(jí) DNS 服務(wù)器浙值,由上一級(jí)服務(wù)器進(jìn)行解析恳不,上一級(jí)服務(wù)器如果不能解析,或找根 DNS 或把轉(zhuǎn)請(qǐng)求轉(zhuǎn)至上上級(jí)亥鸠,以此循環(huán)妆够。不管是本地 DNS 服務(wù)器用的是轉(zhuǎn)發(fā)识啦,還是根提示,最后都是把結(jié)果返回給本地 DNS 服務(wù)器神妹,由此 DNS 服務(wù)器再返回給客戶機(jī)
發(fā)起網(wǎng)絡(luò)
查詢到 IP 地址后由瀏覽器進(jìn)程中的網(wǎng)絡(luò)線程發(fā)起請(qǐng)求
客戶端對(duì)數(shù)據(jù)進(jìn)行處理
發(fā)送數(shù)據(jù)包
- 應(yīng)用層(應(yīng)用層颓哮,表示層,會(huì)話層)鸵荠,應(yīng)用程序處理
編碼處理冕茅,控制何時(shí)建立通信,將數(shù)據(jù)發(fā)送給下一層 - 傳輸層蛹找,TCP 模塊處理
根據(jù)應(yīng)用層的指示姨伤,建立和斷開連接,并提供將數(shù)據(jù)順利發(fā)送到對(duì)端的可靠傳輸庸疾,面向連接的乍楚、可靠的流協(xié)議。通過校驗(yàn)和届慈,序列號(hào)徒溪,確認(rèn)應(yīng)答,重發(fā)控制金顿,連接管理臊泌,以及窗口控制等機(jī)制實(shí)現(xiàn)可靠性傳輸。以段為單位發(fā)送數(shù)據(jù)揍拆,MSS(在三次握手中得出)最大消息長(zhǎng)度渠概,是 IP 中不會(huì)被分片處理的最大數(shù)據(jù)長(zhǎng)度∩┧可利用 TCP 窗口提高速度播揪,無需等待確認(rèn)應(yīng)答而可以繼續(xù)發(fā)送數(shù)據(jù)的最大值,即使部分應(yīng)答未返回顷牌,仍可使用下一個(gè)應(yīng)答進(jìn)行確認(rèn)剪芍。重發(fā)控制,報(bào)文段丟失的情況下窟蓝,同一個(gè)序號(hào)的確認(rèn)應(yīng)答將會(huì)被重復(fù)不斷的返回罪裹,發(fā)送端如果連續(xù)三次收到同一個(gè)確認(rèn)應(yīng)答,則將對(duì)應(yīng)的數(shù)據(jù)重發(fā)运挫,稱為高速重發(fā)控制状共。 - 網(wǎng)絡(luò)層,IP 模塊處理
通過 IP 地址傳輸?shù)椒?wù)端 - 鏈路層谁帕,網(wǎng)絡(luò)接口處理
包含的 MAC峡继,數(shù)據(jù)在每次轉(zhuǎn)發(fā)的過程中更換 MAC 地址,每個(gè)主機(jī)都維護(hù)著一張路由控制表匈挖,該表記錄 IP 數(shù)據(jù)在下一步應(yīng)該發(fā)給哪個(gè)路由器
接收數(shù)據(jù)包
- 網(wǎng)絡(luò)接口的處理
根據(jù)所傳遞的數(shù)據(jù)類型碾牌,將數(shù)據(jù)傳給對(duì)應(yīng)的子程序康愤,如 IP 類型,則傳遞給的處理 IP 的子程序 - IP 模塊的處理
判斷包首部中的 IP 地址與自己的地址是否匹配舶吗,根據(jù)數(shù)據(jù)查找上層協(xié)議征冷,交給指定協(xié)議處理 - TCP 模塊的處理
校驗(yàn)數(shù)據(jù)是否損壞,根據(jù)端口號(hào)確定具體的應(yīng)用程序誓琼,接收完成检激,發(fā)送一個(gè)”確認(rèn)回執(zhí)“給發(fā)送端 - 應(yīng)用程序的處理
應(yīng)用程序接收發(fā)送端發(fā)送的數(shù)據(jù)
瀏覽器渲染
接收數(shù)據(jù)
- 網(wǎng)絡(luò)線程接收到服務(wù)器的響應(yīng)后,開始解析 HTTP 響應(yīng)報(bào)文腹侣,然后根據(jù)響應(yīng)頭中的 Content-Type 字段來確定響應(yīng)主體的媒體類型(MIME Type)叔收,如果媒體類型是一個(gè) HTML 文件,則將響應(yīng)數(shù)據(jù)交給渲染進(jìn)程(renderer process)來進(jìn)行下一步的工作傲隶,如果是 zip 文件或者其它文件饺律,會(huì)把相關(guān)數(shù)據(jù)傳輸給下載管理器。
- 通知 UI 線程數(shù)據(jù)請(qǐng)求完成
- 瀏覽器進(jìn)程發(fā)送 IPC 消息確認(rèn)導(dǎo)航
- 瀏覽器進(jìn)程通過 IPC 管道將數(shù)據(jù)傳遞給渲染進(jìn)程
- 渲染進(jìn)程接收到數(shù)據(jù)之后跺株,又發(fā)送 IPC 消息給瀏覽器進(jìn)程蓝晒,告訴瀏覽器進(jìn)程導(dǎo)航已經(jīng)提交了,頁面開始加載帖鸦,與此同時(shí),導(dǎo)航欄更新胚嘲,安全提示符更新作儿,訪問歷史列表更新
開始渲染
渲染進(jìn)程的主線程將 html 進(jìn)行解析構(gòu)造 DOM 結(jié)構(gòu),生成 DOM 樹馋劈,形成 DOM 樹后不斷向其中添加節(jié)點(diǎn)
知道 DOM 結(jié)構(gòu)和每個(gè)節(jié)點(diǎn)的樣式后攻锰,接下來確定每個(gè)節(jié)點(diǎn)的位置及其所占用的區(qū)域,該節(jié)點(diǎn)稱為 layout 布局
主線程通過遍歷 DOM 和計(jì)算好的樣式生成 layout Tree妓雾。layout Tree 是和最終展示在界面上的一一對(duì)應(yīng)的娶吞,DOM 樹和 layout Tree 是不一樣的,如 display:none 和偽類
主線程遍歷 layout Tree 創(chuàng)建一個(gè)繪制記錄表(Paint Record)械姻, 該表記錄了繪制的順序妒蛇,并生成 layer Tree
-
繪制
- 將 layer Tree 和繪制順序信息傳遞給合成器線程,合成器線程按照規(guī)則分圖層
- 由于每個(gè)圖層可能像頁面的整個(gè)長(zhǎng)度一樣大楷拳,故合成器線程將圖層切分為多個(gè)圖塊(tiles)
- 將每個(gè)圖塊發(fā)送給柵格化線程(Raster Thread)
- 柵格線程?hào)鸥窕總€(gè)圖塊绣夺,并將它們存儲(chǔ)在 GPU 內(nèi)存中
- 當(dāng)柵格完成時(shí),合成器線程將收集稱為“draw quads”的圖塊信息欢揖, 這些信息記錄了圖塊在內(nèi)存中的位置和在頁面的哪個(gè)位置繪制圖塊的信息
- 根據(jù)信息合成器線程生成合成器幀(Frame)
- 該合成器幀通過 IPC 傳送給瀏覽器進(jìn)程
- 瀏覽器進(jìn)程將合成器幀傳送給 GPU
- GPU 渲染展示到屏幕
- 進(jìn)行操作時(shí)陶耍,如滾動(dòng),會(huì)生成新的合成器幀她混,再傳送到 GPU烈钞,再次渲染
其他
- 重排和重繪泊碑,改變?cè)爻叽缥恢脤傩院螅瑫?huì)重新進(jìn)行樣式計(jì)算毯欣,及后續(xù)流程馒过,稱為重排;改變?cè)仡伾珜傩詴r(shí)仪媒,不會(huì)觸發(fā)重新布局沉桌,但還是會(huì)觸發(fā)樣式計(jì)算,稱為重繪
- js 也運(yùn)行在主線程算吩,處理不善會(huì)導(dǎo)致卡頓留凭,如涉及動(dòng)畫可使用 transform,僅在合成器線程和柵格線程中使用偎巢,不會(huì)和 js 搶主線程
- 渲染結(jié)束蔼夜,渲染進(jìn)程向?yàn)g覽器進(jìn)程發(fā)送 IPC 消息,告訴瀏覽器進(jìn)程渲染完成压昼,此時(shí) UI 線程停止 tab 中的加載中圖標(biāo)