自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

網(wǎng)紅面試題:從輸入 Url 到看到頁(yè)面發(fā)生了什么

網(wǎng)絡(luò) 通信技術(shù)
這道題能衍生很多問(wèn)題,從一題可以測(cè)試出面試者的HTTP、瀏覽器相關(guān)知識(shí)。正所謂”鵬怒而飛,其翼若垂天之云;水擊三千里,碧空九萬(wàn)丈;好風(fēng)憑借力,送我上青云?!?。

流程圖

這題扎眼看上去沒(méi)問(wèn)題,無(wú)非是 HTTP 請(qǐng)求到瀏覽器渲染,但可以聊的東西很多。我想它的執(zhí)行順序是,用戶輸入——開(kāi)始導(dǎo)航——HTTP請(qǐng)求——瀏覽器渲染。其中用戶輸入、開(kāi)始導(dǎo)航、瀏覽器渲染是瀏覽器方面的知識(shí)點(diǎn),HTTP請(qǐng)求是 HTTP 方面的知識(shí)點(diǎn)。

以下就是從輸入 url 到看到頁(yè)面的整個(gè)流程圖。

從url輸入到頁(yè)面渲染

前言

了解"開(kāi)始導(dǎo)航"之前,需要先知道瀏覽器架構(gòu),簡(jiǎn)單來(lái)說(shuō),現(xiàn)代瀏覽器由1個(gè)瀏覽器主進(jìn)程、1個(gè)GPU進(jìn)程、多個(gè)渲染進(jìn)程、多個(gè)插件進(jìn)程、網(wǎng)絡(luò)進(jìn)程、音頻進(jìn)程、存儲(chǔ)進(jìn)程組成。

下圖是李兵在《瀏覽器工作原理與實(shí)踐》中所示,展示 Chrome 瀏覽器的架構(gòu)。

目前的瀏覽器架構(gòu)

以及未來(lái)現(xiàn)代瀏覽器架構(gòu)示意圖:

未來(lái)現(xiàn)代chrome瀏覽器架構(gòu)

文章現(xiàn)代瀏覽器內(nèi)部揭秘中有一張圖,是這樣描述的。

現(xiàn)代瀏覽器內(nèi)部解密

圖中表明瀏覽器主進(jìn)程包含了 UI 線程、網(wǎng)絡(luò)線程、存儲(chǔ)線程,與李兵的觀點(diǎn)有所不同。那以誰(shuí)為準(zhǔn)呢?以時(shí)間為準(zhǔn),李兵的專欄是19年所寫(xiě),而《現(xiàn)代瀏覽器內(nèi)部解密》是 18 年的文章,站在 2022 年的背景,現(xiàn)代瀏覽器,UI、網(wǎng)絡(luò)、存儲(chǔ)等都已升級(jí)為進(jìn)程,而非是瀏覽器主進(jìn)程中的線程。

用戶輸入

當(dāng)用戶在地址欄中輸入一個(gè)字符串時(shí),地址欄會(huì)判斷輸入的關(guān)鍵字是搜索內(nèi)容,還是請(qǐng)求的URL。

  • 如果是搜索內(nèi)容,地址欄會(huì)使用瀏覽器默認(rèn)的搜索引擎,合成新的帶搜索關(guān)鍵字的URL 例如在chrome中搜長(zhǎng)澤雅美在chrome中搜長(zhǎng)澤雅美。
  • 如果輸入內(nèi)容符合 URL 規(guī)則,例如輸入azhubaby.com,那么地址欄會(huì)根據(jù)規(guī)則,把這段內(nèi)容加上協(xié)議合成完成的 URL,如 https://azhubaby.com。

當(dāng)用戶輸入關(guān)鍵字并鍵入回車(chē)之后,意味著當(dāng)前頁(yè)面將替換為新的頁(yè)面,此時(shí)瀏覽器中有個(gè) API——beforeunload,它允許頁(yè)面在離開(kāi)之前觸發(fā)是否一個(gè)確認(rèn)對(duì)話框。這里使用此API,可讓瀏覽器不再導(dǎo)航。

// 監(jiān)聽(tīng)離開(kāi)頁(yè)面前的事件
window.addEventListener('beforeunload', (event) => {
event.preventDefault();
event.returnValue = '';
})

可在這里看看 beforeunload 的demo。

從瀏覽器架構(gòu)分工上講,當(dāng)用戶輸入字符串時(shí)是 UI 進(jìn)程(老一點(diǎn)的瀏覽器是瀏覽器主進(jìn)程)在運(yùn)作。

開(kāi)始導(dǎo)航

當(dāng)敲下 Enter 鍵時(shí),UI 進(jìn)程將指揮權(quán)交接給了網(wǎng)絡(luò)進(jìn)程。網(wǎng)絡(luò)進(jìn)程接受請(qǐng)求指令前,會(huì)先查找本地緩存是否有緩存。如果有緩存該資源,那么直接返回資源給瀏覽器進(jìn)程;如果在緩存中沒(méi)找到該資源,那么則正式進(jìn)入HTTP請(qǐng)求階段。

關(guān)于HTTP緩存方面的知識(shí)可以看看這篇——面試常客:HTTP 緩存。

HTTP請(qǐng)求

之前寫(xiě)過(guò)一篇TCP/IP 協(xié)議及網(wǎng)絡(luò)分層模型,講述了 TCP/IP 網(wǎng)絡(luò)分層協(xié)議,它就像搭積木一樣,每一層需要下一層的支撐,我們的 HTTP 請(qǐng)求是其 HTTP 協(xié)議的應(yīng)用,需要先連接傳輸層(TCP)以及更底層網(wǎng)絡(luò)互連層(IP)。

TCP/IP 網(wǎng)絡(luò)分層模型

而IP從哪里來(lái),通過(guò) DNS, 使其域名 和 IP 做映射。

我們使用倒推法可以理清“路線”:

HTTP 請(qǐng)求 —— HTTP 協(xié)議連接 —— TCP 協(xié)議連接 —— IP 協(xié)議連接 —— 需要知道 IP——DNS 做域名/IP映射。

所以進(jìn)入 HTTP 請(qǐng)求的第一步是 DNS 解析。

DNS 解析

這里對(duì) DNS 不做過(guò)多概述,簡(jiǎn)單來(lái)說(shuō),它的作用是用域名代替 IP 地址,符合人的記憶。輸入du.azhubaby.com ,表示 IP 地址 47.102.152.19 ,你可以在命令行中 ping 一個(gè)域名,來(lái)求證一下結(jié)果。

ping域名

HTTP 請(qǐng)求之前的第一步是判斷 DNS 中是否有緩存,如果有,直接返回 IP 地址;如果沒(méi)有,則進(jìn)行 DNS 解析,并把結(jié)果 IP 緩存到 DNS。

有了 IP 地址后,IP 層連接成功,接下來(lái)就是 TCP 傳輸層。

TCP 連接

這里要看HTTP協(xié)議的版本,如果是 HTTP/1.1 的話,就要考慮TCP隊(duì)列否飽滿,因?yàn)?HTTP/1.1 最多允許一個(gè)域名連接 6 條TCP,太多了就要在等待TCP隊(duì)列中排隊(duì);如果是 HTTP/2 的話,那就沒(méi)事,它允許TCP并發(fā)。

這里還要考慮到如果協(xié)議是 HTTPS 協(xié)議的話,還需要建立一條 TLS 連接。

等真正 TCP 連接時(shí),就聯(lián)想到網(wǎng)紅面試題:三次握手、四次揮手。

三次握手、四次揮手

為什么是三次握手和四次揮手,因?yàn)橹挥羞@樣才能讓雙方(客戶端和服務(wù)端)知道彼此的接收能力和發(fā)送能力是沒(méi)問(wèn)題的。

http-tcp-three-handshakes

步驟為:

  • 客戶端提出建立連接,發(fā)出客戶端seq:seq=client_isn。
  • 服務(wù)端收到消息后返回 ack=client_isn+1 和服務(wù)端seq:seq=server_isn。
  • 客戶端收到后返回ack=server_isn+1 表示收到了。

可以理解為男女雙方確認(rèn)關(guān)系,男女雙方要結(jié)婚,怎么辦?先見(jiàn)父母得到父母認(rèn)同,之前聽(tīng)過(guò)這樣一句話:得不到父母祝福的婚姻是不幸福的(當(dāng)然,不見(jiàn)父母直接結(jié)婚的也有,但不主流)。

  • 男方提出去女方家,帶上見(jiàn)面禮seq:seq=男方的誠(chéng)意。
  • 女方家收到見(jiàn)面禮后返回(給男方)紅包 ack=我們認(rèn)可你啦 以及女方去男方家也帶上見(jiàn)面禮seq:seq=女方的誠(chéng)意。
  • 男方家收到見(jiàn)面禮后返回(給女方的)紅包 ack=server_isn+1。

這個(gè)叫確定關(guān)系。所以要又來(lái)又回三次,雙方都確保知道對(duì)方的誠(chéng)意和自己的誠(chéng)意。

那什么是四次揮手呢?

在斷開(kāi)之前,需要進(jìn)行四次揮手。

http-tcp-four-handshakes

為什么要有四次揮手?

主要是為了確保雙方都知道對(duì)方斷開(kāi)連接。

具體步驟為:

  • 客戶端第一次發(fā)送消息給服務(wù)端告訴它需要斷開(kāi)連接。
  • 服務(wù)端收到消息后返回消息告訴客戶端:知道了,為了確保服務(wù)端收到了之前所有的 HTTP 請(qǐng)求,服務(wù)端需要等一等再斷開(kāi)連接。
  • 服務(wù)端確認(rèn)所有的HTTP請(qǐng)求都收到了,主動(dòng)發(fā)消息給客戶端:我這邊所有的請(qǐng)求都處理完了,我也可以斷開(kāi)連接了。
  • 客戶端收到這個(gè)請(qǐng)求后,返回消息告訴服務(wù)端:我知道,斷開(kāi)連接吧。

主要是為了確認(rèn)雙方的接收能力和發(fā)送能力是否正常、制定自己的初始化序列號(hào)為后面的可靠性傳送做準(zhǔn)備。

可以理解為一對(duì)男女要分手。

  • 女方提出分手,說(shuō)你對(duì)我不好,我要分手。
  • 男方覺(jué)得需求合理,同意分手,但分手之前要把聯(lián)系方式、合照、各種亂七八糟的的事情算清楚再分手。
  • 男方理清楚后,主動(dòng)發(fā)消息給女方,說(shuō)這邊都處理清楚了,以后你是你,我是我,我們可以分手了。
  • 女方收到消息后,返回告訴男方:我知道了,分手吧。

于是乎,它們就斷了,分手手續(xù)完成。具體詳細(xì)的信息可看猿人谷的面試官,不要再問(wèn)我三次握手和四次揮手,一個(gè)字:細(xì)。

發(fā)送HTTP請(qǐng)求

TCP連接已經(jīng)通了,現(xiàn)在正式發(fā)送 HTTP 請(qǐng)求,這里又有的聊了,如 HTTP 的報(bào)文內(nèi)容、請(qǐng)求頭、響應(yīng)頭、請(qǐng)求方法、狀態(tài)碼等知識(shí)點(diǎn)。

首先 HTTP 的報(bào)文結(jié)構(gòu)由 起始行 + 頭部 + 空行 + 實(shí)體組成,簡(jiǎn)單來(lái)說(shuō)就是 header+body,HTTP 的報(bào)文可以沒(méi)有body(get方法),但必須要有 header。

請(qǐng)求頭由請(qǐng)求行 + 頭部字段構(gòu)成,響應(yīng)頭由狀態(tài)行 + 頭部字段構(gòu)成。

請(qǐng)求行有三部分:請(qǐng)求方法、請(qǐng)求目標(biāo)和版本號(hào)。

  • 例如 GET / HTTP/1.1。

狀態(tài)行也有三部分:版本號(hào)、狀態(tài)碼和原因字符串。

  • 例如 HTTP/1.1 200 OK。

在瀏覽器中,打開(kāi)F12,在 NetWork 中任何一個(gè)請(qǐng)求中,你都會(huì)看到這樣的結(jié)構(gòu)。

報(bào)文結(jié)構(gòu)

這里我們也常會(huì)遇到一些例如 GET 和 POST 請(qǐng)求方式的區(qū)別、HTTP 狀態(tài)碼等相關(guān)的衍生問(wèn)題。

GET 和 POST 請(qǐng)求方式的區(qū)別

  • 從緩存角度看,GET 會(huì)被緩存,POST 不會(huì)被緩存。
  • 從參數(shù)角度看,GET 通過(guò)在 URL 的"?"后以 key=value 方式傳參,數(shù)據(jù)之間以“&”相連接;POST 則要將數(shù)據(jù)封裝到請(qǐng)求體中發(fā)送,這個(gè)過(guò)程不可見(jiàn)。
  • 從安全角度看,GET 不安全,因?yàn)?URL 可見(jiàn);POST 較 GET 安全度高。
  • 從編碼角度看,GET 只接受 ASCII 字符,向服務(wù)器發(fā)送中文字符可能會(huì)出現(xiàn)亂碼;POST 支持標(biāo)準(zhǔn)字符集,可以正確傳遞中文。
  • 從數(shù)據(jù)長(zhǎng)度的限制看,GET 一般受 URL 長(zhǎng)度限制(URL 的最大長(zhǎng)度是 2048 個(gè)字符),POST 無(wú)限制。

HTTP 狀態(tài)碼

RFC 標(biāo)準(zhǔn)把狀態(tài)碼分成了五類 ,用數(shù)字的第一位表示分類,而 0~99 不用,這樣狀態(tài)碼的實(shí)際可用范圍就大大縮小了,由 000~999 變成了 100~599。

這五類的具體含義是:

  • 1××:提示信息,表示目前是協(xié)議處理的中間狀態(tài),還需要后續(xù)的操作。
  • 2××:成功,報(bào)文已經(jīng)收到并被正確處理。
  • 3××:重定向,資源位置發(fā)生變動(dòng),需要客戶端重新發(fā)送請(qǐng)求。
  • 4××:客戶端錯(cuò)誤,請(qǐng)求報(bào)文有誤,服務(wù)器無(wú)法處理。
  • 5××:服務(wù)器錯(cuò)誤,服務(wù)器在處理請(qǐng)求時(shí)內(nèi)部發(fā)生了錯(cuò)誤。

目前 RFC 標(biāo)準(zhǔn)里總共有 41 個(gè)狀態(tài)碼。

  • 101 - Switching Protocols,客戶端使用 Upgrade 頭字段。
  • 200 - 請(qǐng)求成功。
  • 204 - 無(wú)內(nèi)容,服務(wù)器成功處理了請(qǐng)求,但沒(méi)有返回任何內(nèi)容。
  • 206 - 一般用來(lái)做斷點(diǎn)續(xù)傳,或者是視頻文件等大文件的加載。
  • 301 - 永久重定向。
  • 302 - 臨時(shí)重定向。
  • 304 - 未修改協(xié)商緩存,返回緩存中的數(shù)據(jù)。它不具有通常的跳轉(zhuǎn)含義,但可以理解成 重定向到緩存的文件(即緩存重定向)。
  • 400 - 請(qǐng)求中語(yǔ)法錯(cuò)誤。
  • 401 - 未授權(quán)。
  • 403 - 服務(wù)器收到請(qǐng)求,但是拒絕提供服務(wù),即資源不可用。
  • 404 - 無(wú)法找到請(qǐng)求資源。
  • 408 Request Timeout - 請(qǐng)求超時(shí)。
  • 414 - 請(qǐng)求 URI 過(guò)長(zhǎng)(如圖一新浪常有)。
  • 500 - 服務(wù)器內(nèi)部錯(cuò)誤。
  • 501 - 尚未實(shí)施:服務(wù)器不具備請(qǐng)求功能。
  • 502 - 網(wǎng)關(guān)錯(cuò)誤。
  • 503 - 服務(wù)器不可用,主動(dòng)用503響應(yīng)請(qǐng)求或 Nginx 設(shè)置限速,超過(guò)限速,會(huì)返回503。
  • 504 - 網(wǎng)關(guān)超時(shí)。

這里要對(duì) 304 做一下說(shuō)明,當(dāng)請(qǐng)求頭 If-Modified-Since 或 If-None-Match 中判斷修改時(shí)間是否一致(或唯一標(biāo)識(shí)是否一致),是,則返回304,使用瀏覽器內(nèi)存中的本地緩存;不一致則說(shuō)明要更新,繼續(xù)請(qǐng)求資源放回給客戶端,并帶上 Last-Modified 或 ETag。

請(qǐng)求方式

HTTP/1.1 規(guī)定了八種方法,都必須是大寫(xiě)形式。

  • GET:獲取資源,可以理解為讀取或者下載數(shù)據(jù)。只有GET請(qǐng)求才能起到緩存效果。
  • HEAD:獲取資源的元信息。
  • POST:像資源提交數(shù)據(jù),相當(dāng)于寫(xiě)入或上傳數(shù)據(jù)。
  • PUT:類似 POST。
  • DELETE:刪除資源。
  • CONNECT:建立特殊的連接隧道。
  • OPTIONS:列出可對(duì)資源實(shí)行的方式。
  • TRACE:追蹤請(qǐng)求 - 響應(yīng)的傳輸路徑。

瀏覽器渲染

當(dāng)HTTP 請(qǐng)求完畢后,斷開(kāi) TCP 連接,將資源返回給客戶端(瀏覽器)。此時(shí)瀏覽器要判斷是否與打開(kāi)的網(wǎng)站是同一個(gè)站點(diǎn)。因?yàn)槿绻峭粋€(gè)站點(diǎn)的話,則可使用同站點(diǎn)的渲染進(jìn)程渲染頁(yè)面,如果不是,瀏覽器則打開(kāi)新的渲染進(jìn)程解析資源。

瀏覽器渲染的大致流程如下圖所示:

瀏覽器渲染大致流程

我們可以將頁(yè)面渲染分為三個(gè)步驟:

解析

  • HTML 被解析為 DOM 樹(shù),CSS 被解析為 CSS 規(guī)則樹(shù),JavaScript 通過(guò) DOM API 和 CSSOM API 來(lái)操作 DOM Tree 和 CSS Rule Tree。

渲染

  • 瀏覽器引擎通過(guò) DOM Tree 和 CSS Rule Tree 構(gòu)建 Rendering Tree(渲染樹(shù)),這其中進(jìn)行大量的 回流(Reflow) 和 重繪(Repaint)。
  • 回流和重繪 回流:意味著元件的幾何尺寸變了,需要重新驗(yàn)證并計(jì)算 Render Tree重繪:屏幕的一部分需要重畫(huà),比如某個(gè)CSS 的背景色變了,但元件的幾何尺寸沒(méi)有變回流的成本要比重繪大。

繪制

  • 最后通過(guò)操作系統(tǒng)(瀏覽器)的Native GUI的API繪制。

其中,衍生出重繪和回流的問(wèn)題,提高性能的方法之一就是減少瀏覽器的渲染時(shí)間,其中的一個(gè)優(yōu)化點(diǎn)就是減少重繪和回流。

減少回流和重繪的方法

  1. 不要一條條修改 DOM 樣式,與其這樣,不如預(yù)定義好CSS的class,然后修改DOM的樣式。
  2. 把DOM“離線”后修改 使用 documentFragment 對(duì)象在內(nèi)存里操作 DOM先把 DOM 給 display:none(有一次 。 Reflow),然后你想怎么改就怎么改,再把它顯示出來(lái)clone 一個(gè) DOM 節(jié)點(diǎn)到內(nèi)存里,然后想怎么改就怎么改,改完后和在線的那個(gè)交換一下。
  3. 不要把 DOM 節(jié)點(diǎn)的屬性值放在一個(gè)循環(huán)中當(dāng)作循環(huán)的變量,不然這會(huì)導(dǎo)致大量地讀寫(xiě)這個(gè)節(jié)點(diǎn)的屬性
  4. 盡可能地修改層級(jí)比較低的DOM。
  5. 不要使用 table 布局。

造成回流的屬性:

width、height、padding、margin、border、position、top、left、bottom、right、float、clear、text-align、vertical-align、line-height、font-weight、font-size、font-family、overflow、white-space

造成重繪的屬性:

color、border-style、border-radius、text-decoration、box-shadow、outline、background

記住一點(diǎn),回流是與幾何大小相關(guān),重繪與大小無(wú)關(guān)。

如此,從輸入 url 到看到頁(yè)面的整個(gè)流程就走完了。

總結(jié)

這道題能衍生很多問(wèn)題,從一題可以測(cè)試出面試者的HTTP、瀏覽器相關(guān)知識(shí)。正所謂”鵬怒而飛,其翼若垂天之云;水擊三千里,碧空九萬(wàn)丈;好風(fēng)憑借力,送我上青云?!啊_@道題之所以能成為經(jīng)典題,不是沒(méi)有它的原因的。

筆者這里做一個(gè)總結(jié),把這題可以衍生的知識(shí)點(diǎn)逐一列出,待君思索。

瀏覽器方面

  • 瀏覽器架構(gòu) 由什么組成?瀏覽器主進(jìn)程、GPU進(jìn)程、多個(gè)渲染進(jìn)程、多個(gè)插件進(jìn)程、網(wǎng)絡(luò)進(jìn)程、音頻進(jìn)程、存儲(chǔ)進(jìn)程等渲染進(jìn)程中有哪些進(jìn)程?GUI渲染線程、JS 引擎線程、事件觸發(fā)線程、網(wǎng)絡(luò)異步線程、定時(shí)器線程進(jìn)程和線程的區(qū)別?進(jìn)程是應(yīng)用程序創(chuàng)建的實(shí)例,而線程依托于進(jìn)程,它是計(jì)算機(jī)最小的運(yùn)行單位。
  • 瀏覽器渲染 渲染流程?解析、渲染、繪制重繪和回流 兩者的區(qū)別重繪和回流的屬性如何減少重繪和回流,提高渲染性能。

HTTP方面

  • HTTP緩存 強(qiáng)緩存 HTTP/1.1 Cache-ControlHTTP/1.0 ExpiresCache-Control > Expires 協(xié)商緩存 HTTP/1.1 ETag/If-None-MatchHTTP/1.0 Last-Modified/If-Modified-Since精準(zhǔn)度:ETag > Last-Modified性能:Last-Modified > ETag。

TCP/IP 連接 三次握手、四次揮手

  • 網(wǎng)絡(luò)層面的性能優(yōu)化 HTTP/1.1的做法HTTP/2 的做法HTTP/3 的做法每個(gè)階段采用的性能優(yōu)化是有所不同的。
責(zé)任編輯:姜華 來(lái)源: 今日頭條
相關(guān)推薦

2023-01-14 16:11:27

瀏覽器URL回車(chē)

2017-04-11 13:54:49

HTTPURLHTML

2017-09-22 13:24:20

2020-01-10 08:54:24

URLDNSTCP

2022-05-26 23:36:36

SQLMySQL數(shù)據(jù)

2020-08-24 07:12:17

前端CRP性能優(yōu)化

2019-12-20 09:31:23

TCPHTTP瀏覽器

2021-05-27 10:26:00

地址欄URLhttp

2020-10-29 07:05:30

Main函數(shù)Python

2011-03-31 09:20:45

URLDNSWeb應(yīng)用程序

2017-09-06 09:13:24

2024-05-06 10:53:22

瀏覽器TCPHTTPS

2020-09-01 11:40:01

HTTPJavaTCP

2018-01-03 15:17:26

2013-01-05 14:51:34

JavaScriptjQuery面試

2025-02-11 07:40:27

2020-10-09 08:59:55

輸入網(wǎng)址解密

2023-11-02 08:00:00

ClickHouse數(shù)據(jù)庫(kù)

2022-01-10 08:50:13

URL前端頁(yè)面

2024-05-07 08:47:55

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)