一个页面从输入URL到加载显示完成,发生了什么?
生活随笔
收集整理的這篇文章主要介紹了
一个页面从输入URL到加载显示完成,发生了什么?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
面試經典題——URL加載
一、涉及基本知識點:
1. 計算機網絡
五層因特爾協議棧:
- 應用層(dns、http):DNS解析成IP并完成http請求發送;
- 傳輸層(tcp、udp):三次握手四次揮手模式建立tcp連接;
- 網絡層(IP、ARP):IP尋址;
- 數據鏈路層(PPP):將請求數據封裝成幀;
- 物理層:利用物理介質傳輸比特流(傳輸的時候通過雙絞線、電磁波等)
- OIS七層框架:多了兩層即,會話層(處理兩個通信系統中交換信息的表示方式)和表示層(管理不同用戶和進程之間的對話)。
get和post的區別:
- get產生一個tcp數據包,post產生兩個
- get請求時會把headers和data數據一起發送出去;
- post請求時,瀏覽器先發送headers,服務器100繼續,瀏覽器再發送data。
DNS查詢得到IP
詢問遞歸式DNS服務器:
- 如果信息不存儲在本地,計算機會聯系您的ISP(網絡提供商)的遞歸DNS服務器;
- 這些專用計算機會為你執行一個DNS查詢工作;
- 遞歸服務器有自己的緩存,所以這個查詢過程通常在這里完成,并將信息還回給用戶;
詢問根域名服務器
- 如果遞歸服務器沒有答案,他們會查詢根域名服務器;
- 根域名服務器是一種計算機,它扮演著一種DNS的電話接線員的角色,他們不知道答案,但可以將我們的疑問指向知道在哪里可以找到答案的人。
詢問TLD域名服務器:
- 根域名服務器將查看請求的第一部分,按從右到左的順序,從www.dyn.com中找到.com,并將請求指向.com對應的頂級域名服務器(TLD).com;
- 每個TLD,如(.com,.org,.us)都有自己的頂級域名服務器,
- 這些服務器沒有我們需要的信息,但他們可以直接將我們引導到有信息的服務器。
詢問權威的DNS服務器
- TLD域名服務器會繼續檢查請求的下一部分(dyn)www.dyn.com,并將查詢指向負責此特定域名的服務器;
- 這些權威的服務器將負責了解關于特定域的所有信息,并將信息存儲在DNS記錄。
找回記錄:
-遞歸服務器從權威服務器中檢索dyn.com的記錄,并將記錄存儲在本地緩存;
- 如果其他任何人請求dyn.com的主機記錄,遞歸服務器已經有答案了,并不需要再次進行查找;
- 所有記錄都有一個期限,一段時間后,遞歸服務器將需要要求一個新的記錄副本,以確保信息不回過時。
接收答案:
- 有了答案,遞歸服務器將記錄返回到計算機,
- 您的計算機將記錄存儲在緩存中,從記錄中讀取IP地址,然后將這些信息傳遞給瀏覽器;
- 然后瀏覽器就可以根據IP地址和服務器進行連接建立。
TCPIP請求
- http的本質就是TCPIP請求;
- 需要經歷3次握手建立連接,4次揮手斷開連接;
- TCP將http長報文劃分為短報文,通過三次握手與服務器端建立連接,進行可靠傳輸。
-
三次握手:
- 客戶端:你是XXX服務端嗎?
- 服務端: 我是XXX服務端,你是客戶端嗎?
- 客服端: 是的,我是客戶端
- 建立連接成功后,接下來就可以進行正式的傳輸數據。
-
四次揮手斷開連接
- 主動方:我已經關閉了向你那邊的信息發送通道,只能被動接受信息了;
- 被動方: 收到通道關閉的信息;
- 被動方: 我現在也關閉了向你那邊發送信息的通道
- 主動方: 左后收到信息,連接斷開,之后雙方無法通信
TCP/IP的并發限制:
- 瀏覽器對同一個域名下并發的TCP連接是有限制的(2-10個不等)
- 而且在http1.0中往往一個資源的下載就需要一個tcp/ip請求
2. 瀏覽器機制
(1)進程和線程的概念
(2)多進程的瀏覽器
瀏覽器是多進程的,有一個主控進程,以及每一個tab頁面都會開一個進程(某些情況下多個tab由于優化策略會合并)- 瀏覽器主要進程:
Browser進程:瀏覽器的主進程,負責協調、主控,只有一個,作用:
- 負責瀏覽器界面的顯示、與用戶交互(如前進、后退等)
- 負責各個頁面的管理,創建和銷毀其他進程;
- 將Renderer進程得到的內存中的Bitmap繪制到用戶界面上
- 網絡資源的管理和下載等
瀏覽器渲染進程(Renderer進程、瀏覽器內核、內部是多線程):
- 默認沒打開一個tab頁面,就會啟動一個Renderer進程;
- 負責頁面的渲染,腳本的執行,事件的處理。
-
瀏覽器多進程的優勢
- 避免單個page crash影響整個瀏覽器;
- 避免第三方插件crash影響整個瀏覽器
- 多進程充分利用多核優勢;
- 方便使用沙盒模型隔離插件等進程,提高瀏覽器穩定性
瀏覽器內核(渲染進程)
- 瀏覽器渲染進程內部是多線程,包含主要線程有:
1.GUI渲染線程:
- (1)負責瀏覽器界面的渲染,解析HTML、CSS,構建DOM樹和RenderObject樹,布局和繪制等;
- (2) 當界面需要重繪(Repaint)或由于某種操作引發回流(reflow)時該線程會執行;
- 注意:GUI渲染線程和JS引擎線程是互斥的,當JS引擎執行時GUI線程會被掛起,GUI更新會保存在一個隊列中等JS引擎空閑時立即執行。
2.JS引擎線程:
- JS內核,負責處理JavaScript腳本程序(V8引擎)
- 負責解析JavaScript腳本,運行代碼;
- JS引擎一直等待著任務隊列中的任務到來,然后加以處理,一個tab頁面(renderer進程)中無論什么時候都只有一個JS線程在運行JS程序;
- 注意:由于GUI渲染線程和JS引擎線程是互斥的,所以如果JS程序運行時間過長,這樣會導致頁面渲染不連貫,導致頁面渲染加載阻塞;
3.事件觸發線程:
- 歸屬于瀏覽器,而不是JS引擎,用來控制事件循環;
- 當JS引擎執行代碼塊如setTimeOut時(也可以來自瀏覽器內核的其他線程,如鼠標單擊事件、AJAX異步請求等),會將對應的任務添加到事件線程中;
- 當對應的事件符合觸發條件被觸發時,該線程就會把事件添加到JS的待處理隊列的隊尾,等待JS引擎的處理;
- 注意:由于JS的單線程的關系所以這些待處理隊列中的事件都得排隊等待JS引擎處理(當JS引擎空閑時才會去執行)。
4.定時觸發器線程:
- setTimeOut與setInterval所在的線程;
- 瀏覽器的定時計數器并不是由JavaScript引擎計數的,(因為JavaScript是單線程,如果處于阻塞狀態就會影響計時的準確)因此通過單獨的線程來計時并觸發定時(計時完畢后,添加到事件隊列,等待JS引擎空閑時執行)
5.異步http請求線程:
- 在XMLHttpRequest在連接后是通過瀏覽器新開一個線程請求的
- 將檢測到狀態變更時,如果設置有回調函數,異步線程就將產生狀態變更事件,將這個回調在放到事件隊列中,再由JavaScript引擎執行。
一、 一個頁面從輸入URL到加載顯示完成,這個過程發生了什么?
-
簡潔版:
- 瀏覽器根據請求的URL交給DNS域名解析,找到真實的IP,向服務器發起請求;
- 服務器交給后臺處理完成后返回數據,瀏覽器接收文件(HTML、CSS、JavaScript等);
- 瀏覽器對加載到的資源(HTML、CSS、JavaScript等)進行語法解析,構建相應的內部數據結構(DOM樹、CSS樹、render樹等);
- 載入解析到的資源文件、渲染頁面、完成。
-
詳細版:
- 首先瀏覽器開啟一個線程來處理這個請求,對URL分析判斷,如果是http協議就按照Web方式來處理;
- 其次瀏覽器會對URL進行解析,一般包括(協議頭、主機域名或IP地址、端口號、請求路徑、查詢參數、hash等),然后開啟網絡線程發出一個完整到http請求;
- 當然一般我們輸入的URL是服務器域名,這時就需要DNS通過域名查詢得到對應的IP;
- DNS首先會查看瀏覽器DNS緩存,沒有就查詢計算機本地DNS緩存,還沒有就詢問遞歸式DNS服務器(即網絡提供商,一般這個服務器都會有自己的緩存,所以IP查詢一般在這里完成),如果沒有緩存,那就需要通過根域名和TLD域名服務器指到對應的權威DNS服務器找回記錄,并緩存到遞歸式服務器,然后遞歸服務器在將記錄返回給本地。
- 有了IP地址,此時網絡層便會通過IP地址尋的對應服務器的物理地址
- 尋得服務器地址,客戶端在網絡傳輸層便可以和服務器通過三次握手建立tcpip連接
- 連接建立后網絡數據鏈路層將數據包裝成幀;
- 最后物理層利用物理介質進行傳輸;
- 到了服務器,就會通過相反的方式將數據一層一層的還原回去;
- 請求到了后臺服務器,一般會有統一的驗證,如安全驗證、跨域驗證等,驗證未通過就直接返回相應的http報文
- 驗證通過后,就會進入后臺代碼,此時程序收到請求,然后執行對應的操作(如查詢數據庫等);
- 如果瀏覽器訪問過,且緩存上有對應的資源,便會與服務器最后修改時間對比,一致便返回304,告訴瀏覽器可使用本地緩存;
- 前端瀏覽器接收到響應成功的報文后便開始下載網頁
-
下載完的網頁將被交給瀏覽器內核(渲染進程)進行處理:
- 根據頂部定義的DTD類型進行對應的解析方式;
- 渲染進程內部是多線程的,網頁的解析將會被交給內部的GUI渲染線程處理;
- 首先渲染線程中的HTML解釋器,將HTML網頁和資源從字節流解釋轉換成字符流;
- 再通過詞法分析器將字符流解釋成詞語;
- 之后經過語法分析器根據詞語構建成節點;最后通過這些節點組建一個DOM樹;
- 這個過程中,如果遇到的DOM節點是JavaScript代碼,就會調用JavaScript引擎對JavaScript代碼進行解釋執行,此時由JavaScript引擎和GUI渲染線程的互斥,GUI渲染線程就會被掛起,渲染過程停止;如果JavaScript代碼的運行中對DOM樹進行了修改,那么DOM的構建需要從新開始;
- 如果節點需要依賴其他資源,如(圖片,CSS等),便會調用網絡模塊的資源加載器來加載它們,但它們是異步的,不會阻塞當前DOM樹的構建;
- 如果遇到的是JavaScript資源URL(沒有標記異步),則需要停止當前DOM的構建,直到JavaScript的資源加載并被JavaScript引擎執行后才繼續構建DOM;
- 對于CSS,CSS解釋器會將CSS文件解釋成內部表示結構,生成CSS規則樹;
- 然后合并CSS規則樹和DOM樹,生成render渲染樹;
- 最后對render樹進行布局和繪制,并將結果通過IO線程傳遞給Browser控制進程進行顯示。
原文地址:https://segmentfault.com/a/1190000014872028
更多專業前端知識,請上 【猿2048】www.mk2048.com 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的一个页面从输入URL到加载显示完成,发生了什么?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在vue项目中引用element-ui时
- 下一篇: Angular网络请求的封装