常見面試題:地址欄輸入url按回車發(fā)生了什么?(越詳細(xì)越好)

很熟悉的標(biāo)題,總結(jié)一下自己的理解,歡迎各位同行賜教!:)

總結(jié)依據(jù)webkit技術(shù)內(nèi)幕http權(quán)威指南兩書

一:輸入url,url的組成,有什么用?

通常最簡單的url,就像這樣:http://www.lxweimin.com/,這串url就包含方案(就是通信協(xié)議,常見的http,https),服務(wù)器地址(www.lxweimin.com),端口號(http協(xié)議默認(rèn)是80端口,https協(xié)議默認(rèn)是443端口,https就是加密的http協(xié)議,就是在http和TCP之間加了一層TSL或者SSL的安全層),資源(默認(rèn)是index.html)。

二:通過url解析出ip地址(到了我們常說的DNS域名解析了)

1.我們來看第一次訪問某個站點(diǎn)的時候要做什么?

如上所訴,url解析出了服務(wù)器域名,現(xiàn)在要將域名解析出ip地址,就要請求域名服務(wù)器來解析ip,比如www.lxweimin.com.這個域名,后面多了一個點(diǎn),這個點(diǎn)就表示公網(wǎng),通常是省略的,域名解析就是從右向左開始解析,解析.域->com域->jianshu.com域->www.lxweimin.com域這樣就拿到ip地址(其中的查找過程也是很復(fù)雜的,這里我們只概括),如下解析過程:

用戶發(fā)起請求->操作系統(tǒng)把域名發(fā)送給本地區(qū)的域名服務(wù)器->有就解析返回ip,然后結(jié)束;

用戶發(fā)起請求->操作系統(tǒng)把域名發(fā)送給本地區(qū)的域名服務(wù)器->沒有->到Root Server的域名服務(wù)器請求解析->返回一個主域名(.com)的服務(wù)器地址地址->本地的域名服務(wù)器再向主域名服務(wù)器發(fā)起請求->返回Name Server域名服務(wù)器地址(jianshu.com)->接下來的解析就由域名提供商的服務(wù)器來解析->Name Server域名服務(wù)器查詢存儲的域名和ip的映射關(guān)系表->返回ip地址和一個過期時間,根據(jù)這個時間緩存到本地,解析結(jié)束。

2.第二次再訪問同樣站點(diǎn)的時候要做什么?

通常第一次訪問完成之后,瀏覽器會將域名解析的映射緩存到本地,下次再訪問該站點(diǎn)的時候,會先從瀏覽器的緩存中查看有沒有這個域名被解析過得ip地址,有沒有過期等,如果有這個ip而且沒有過期,解析過程就結(jié)束。如果瀏覽器的緩存中沒有,瀏覽器就會查找操作系統(tǒng)的緩存中是否有對應(yīng)域名的ip地址(操作系統(tǒng)的域名解析也有一個過程的,大家可以自行搜索)。


瀏覽器的dns緩存目錄


三:ip地址解析完成之后,就開始發(fā)請求

前面通過url解析出方案,端口號,域名服務(wù)器解析出ip地址,此時瀏覽器發(fā)起到122.228.25.221端口80的TCP連接,在建立連接之前瀏覽器和服務(wù)器會進(jìn)行三次握手

第一次:瀏覽器向服務(wù)器發(fā)送請求(SYN=1),等待服務(wù)器確認(rèn);

第二次:服務(wù)器收到請求并確認(rèn),回復(fù)一個指令(SYN=1,ACK=1);

第三次:客戶端收到服務(wù)器的回復(fù)指令,并返回確認(rèn)(ACK=1);

1.首先瀏覽器發(fā)送連接請求報文,2.服務(wù)器接受連接后回復(fù)ACK報文,并為這次連接分配資源。3.瀏覽器接收到ACK報文后也向服務(wù)器發(fā)生ACK報文,并分配資源,這樣TCP連接就建立了,開始數(shù)據(jù)傳輸。瀏覽器向服務(wù)器發(fā)送http的請求報文,瀏覽器從服務(wù)器讀取響應(yīng)報文,然后瀏覽器關(guān)閉連接。

綜合前兩個的過程大致如下圖:


從域名解析到發(fā)起請求的大致過程


四:服務(wù)器返回html文檔之后,瀏覽器的渲染引擎開始dom解析過程(構(gòu)建DOM樹->渲染樹(Render tree)->布局render樹->繪制render樹)

1.通過網(wǎng)絡(luò)請求拿到html文檔之后,渲染引擎會調(diào)用html解析器開始解析html,將html的標(biāo)簽解析成dom樹,如果遇到靜態(tài)資源,link標(biāo)簽則去請求相應(yīng)的資源,遇到script標(biāo)簽就會調(diào)用js引擎解釋并執(zhí)行(全局執(zhí)行js代碼的時候,dom樹是禁止被訪問的,因為js也可以操作dom結(jié)構(gòu),此時dom樹并沒有創(chuàng)建完成,所以js我們大都建議放在body元素之后(因為有些js執(zhí)行期間可能會很耗時),這樣就不會阻止其他資源的下載)。

解析dom樹的過程:通過網(wǎng)絡(luò)請求獲取的html網(wǎng)頁或資源從字節(jié)流解碼成字符流,然后通過詞法分析器解析成詞語,之后經(jīng)過語法分析器構(gòu)建成節(jié)點(diǎn),最后這些節(jié)點(diǎn)組成一顆dom樹;(當(dāng)dom樹構(gòu)建完成之后,webkit會觸發(fā)DOMContentLoaded事件,jquery的dom ready源碼實(shí)現(xiàn)也用到這個事件,當(dāng)所有資源全都加載完畢之后會觸發(fā)onload事件


從資源的字節(jié)流到dom樹

2.dom樹解析完成之后,渲染引擎調(diào)用css解釋器根據(jù)css規(guī)則為每個dom樹節(jié)點(diǎn)計算css樣式信息,構(gòu)建渲染樹(Render tree);

render tree的過程:渲染引擎調(diào)用css解釋器,根據(jù)css規(guī)則(解析外部或者內(nèi)部引用額樣式表),解析出樣式信息,構(gòu)建render tree,渲染樹會忽略掉不需要被渲染的元素(display:none,head,meta...);

3.布局樹(render layer)

構(gòu)建render tree之后,每個元素并不知道自己的大小顏色等樣式和位置信息,渲染引擎根據(jù)包含塊和盒模型來計算元素的大小位置等信息,這就是布局計算(排版)。布局計算是一個遞歸過程:一個節(jié)點(diǎn)的大小要根據(jù)子節(jié)點(diǎn)的位置大小來計算,一旦布局發(fā)生變化,就要重新繪制,渲染效率就會降低,通常網(wǎng)頁性能瓶頸大都是頻繁的dom操作造成的,現(xiàn)在react框架的diff算法,建立虛擬dom對比上一次的dom,只繪制發(fā)生改變的那部分,大大提升性能。

4.繪制render樹

渲染引擎開始繪制圖像(繪制這部分很復(fù)雜,不說了,你猜我知道不知道!)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容