地址欄輸入URL
檢查URL
瀏覽器的瀏覽器進程檢查URL,組裝協(xié)議躁劣,構(gòu)成完整的URL晃琳,通過進程間通信IPC把URL請求發(fā)送給網(wǎng)絡(luò)進程
發(fā)起http請求
網(wǎng)絡(luò)進程接收到URL發(fā)起http請求
網(wǎng)絡(luò)進程首先查找本地是否存在緩存
如果沒有緩存就進行網(wǎng)絡(luò)請求
網(wǎng)絡(luò)請求首先進行DNS解析拨匆,DNS查過過程也存在緩存的問題姆涩,最終拿到目標服務(wù)器的ip
網(wǎng)絡(luò)進程通過ip地址和服務(wù)器建立tcp鏈接
網(wǎng)絡(luò)進程構(gòu)建請求行,請求頭惭每,請求體骨饿,發(fā)起網(wǎng)絡(luò)請求
拿到響應(yīng)后
瀏覽器根據(jù)相應(yīng)的狀態(tài)嗎判斷是否進行重定向
瀏覽器根據(jù)相應(yīng)的content-type決定如何顯示相應(yīng)的內(nèi)容
如果是text/html,瀏覽器為每個頁面分配一個渲染進程,如果屬于same-site(根域名和協(xié)議完全一致就屬于same-site),就在同一渲染進程進行渲染。
渲染進程準備好之后瀏覽器進程發(fā)出提交文檔指令,這里的文檔指的是響應(yīng)體數(shù)據(jù)宏赘,渲染進程收到指令后建立和網(wǎng)絡(luò)進程的數(shù)據(jù)管道
等文檔數(shù)據(jù)傳輸完成后绒北,渲染進程返回確認提交的消息給瀏覽器進程
瀏覽器進程收到確認提交消息后,更新瀏覽器的界面察署,包括前進后退的歷史狀態(tài)闷游,安全狀態(tài),地址欄的URL,和正真的web頁面
文檔提交后渲染進程開始頁面解析和子資源加載
渲染流程:
構(gòu)建 DOM 樹
輸入:HTML 文檔贴汪;
處理:HTML 解析器解析脐往;
輸出:DOM 數(shù)據(jù)解構(gòu)。
樣式計算
輸入:CSS 文本嘶是;
處理:屬性值標準化钙勃,每個節(jié)點具體樣式(繼承、層疊)聂喇;
輸出:styleSheets(CSSOM)辖源。
布局(DOM 樹中元素的計劃位置)
DOM & CSSOM 合并成渲染樹;
布局樹(DOM 樹中的可見元素)希太;
布局計算克饶。
分層
特定節(jié)點生成專用圖層,生成一棵圖層樹(層疊上下文誊辉、Clip矾湃,類似 PhotoShop 里的圖層);
擁有層疊上下文屬性(明確定位屬性堕澄、透明屬性邀跃、CSS 濾鏡、z-index 等)的元素會創(chuàng)建單獨圖層蛙紫;
沒有圖層的 DOM 節(jié)點屬于父節(jié)點圖層拍屑;
需要剪裁的地方也會創(chuàng)建圖層。
繪制指令
輸入:圖層樹坑傅;
渲染引擎對圖層樹中每個圖層進行繪制僵驰;
拆分成繪制指令,生成繪制列表唁毒,提交到合成線程蒜茴;
輸出:繪制列表。
分塊
合成線程會將較大浆西、較長的圖層(一屏顯示不完粉私,大部分不在視口內(nèi))劃分為圖塊(tile, 256256, 512512)。
光柵化(柵格化)
在光柵化線程池中室谚,將視口附近的圖塊優(yōu)先生成位圖(柵格化執(zhí)行該操作)毡鉴;
快速柵格化:GPU 加速崔泵,生成位圖(GPU 進程)秒赤。
合成繪制
繪制圖塊命令——DrawQuad猪瞬,提交給瀏覽器進程;
瀏覽器進程的 viz 組件入篮,根據(jù)DrawQuad命令陈瘦,繪制在屏幕上。
頁面完成
頁面生成完成后潮售,渲染進程發(fā)送消息給瀏覽器進程痊项,收到后會停止標簽欄上圖標的加載動畫
over
優(yōu)化
渲染進程的主線程按照順序首先構(gòu)建dom樹,樣式計算酥诽,布局鞍泉,繪制
如果發(fā)生重排(比如改變元素大小等)會直接從樣式計算開始從新執(zhí)行,如果發(fā)生重繪(例如改變顏色)會直接從繪制階段開始從新執(zhí)行肮帐,所以頻繁的占用渲染進程的主進程咖驮,就會產(chǎn)生較大的開銷。所以在性能優(yōu)化中训枢,減少重排和重繪的屬性托修,渲染引擎將跳過布局和繪制,只執(zhí)行非主線程的合成恒界,例如:CSS的transform就避開重排和重繪睦刃,直接在非主線程上執(zhí)行合成操作,沒有占用主線程資源十酣,所以效率最高
HTML渲染流程
在上圖中一并畫了出來涩拙,需要經(jīng)過以下幾個階段:構(gòu)建 DOM 樹--->樣式計算--->布局--->分層--->繪制--->分塊--->光柵化--->合成
DNS
DNS 的解析是一個遞歸流程,順序如下圖中數(shù)字標記所示:
- 根 DNS 服務(wù)器:返回頂級域 DNS 服務(wù)器的 IP 地址耸采。
扯一句:世界上有13臺根服務(wù)器兴泥,而有N臺根鏡像服務(wù)器,所以有些國外地址會被墻 ~~~洋幻,說明域名解析第一步并不是走的根服務(wù)器郁轻,而是由根鏡像服務(wù)器控制住做了過濾,有選擇性地進行了域名解析文留,所以如果根域名服務(wù)器出了問題好唯,我覺得我們國內(nèi)仍然可以做到正常訪問,當(dāng)然只是新更新的域名無法訪問燥翅。 - 頂級 DNS 服務(wù)器:返回權(quán)威 DNS 服務(wù)器的 IP 地址
- 權(quán)威 DNS 服務(wù)器:返回相應(yīng)主機的 IP 地址
JS 棧 垃圾數(shù)據(jù)回收
- 示例代碼1:
function hello () {
let name = '數(shù)據(jù)'
}
hello()
console.log(name) // Uncaught ReferenceError: name is not defined 在執(zhí)行上下文時骑篙,存放在棧內(nèi)存中的name地址和數(shù)據(jù)【內(nèi)存塊】已經(jīng)回收掉了,所以在全局上下文中是訪問不到森书。
- 示例代碼2:
function hello () {
let name = '前端食堂'
let food = { name: '回鍋肉' }
function world () {
var description = { slogan: '吃好每一頓飯' }
}
world()
}
hello()
上面的代碼所對應(yīng)的內(nèi)存堆棸卸耍空間如下圖所示:
棧中的垃圾回收比較簡單谎势,當(dāng)一個函數(shù)執(zhí)行結(jié)束后,JavaScript 引擎會通過向下移動 ESP 來銷毀函數(shù)調(diào)用棧中所保存的執(zhí)行上下文杨名,ESP 就是記錄當(dāng)前執(zhí)行狀態(tài)的指針脏榆。
- 垃圾回收操作會暫停 JavaScript 的運行,回收完畢后才會恢復(fù)執(zhí)行台谍,這種行為就是全停頓须喂。
為了降低全停頓所帶來的卡頓,V8 引擎采用了增量標記(Incremental Marking) 算法進行優(yōu)化趁蕊,將標記過程分為一個個小任務(wù)坞生,這些小任務(wù)的執(zhí)行時間比較短,可以穿插在其他的 JavaScript 任務(wù)中間執(zhí)行掷伙,這樣就不會有明顯的卡頓了是己。
當(dāng)然,V8 所采用的優(yōu)化方案不只這一種任柜,而是多種方案綜合使用的卒废,除了增量回收還有并行回收、并發(fā)回收等乘盼。
并行回收:垃圾回收器會使用多個輔助線程來并行執(zhí)行垃圾回收
并發(fā)回收:回收線程在執(zhí)行 JavaScript 的過程中升熊,輔助線程在后臺執(zhí)行垃圾回收
如果你了解【** React 的 Concurrent 模式中時間切片的原理 **】,它的實現(xiàn)思想是不是與增量標記算法有異曲同工之妙呢绸栅。
其中在頁面渲染以及網(wǎng)絡(luò)請求響應(yīng)的性能優(yōu)化方面可以做的優(yōu)化工作有:
1.DNS優(yōu)化
2.將js寫在body尾部级野,使不阻塞渲染頁面
3.預(yù)加載或懶加載
4.資源壓縮,減少請求次數(shù)