從輸入U(xiǎn)RL到頁(yè)面顯示的過程
1. 發(fā)送URL梧乘,請(qǐng)求IP地址
當(dāng)發(fā)送一個(gè)URL請(qǐng)求時(shí)巍佑,不管這個(gè)URL是web頁(yè)面的url還是web頁(yè)面上每個(gè)資源的url,瀏覽器都會(huì)開啟一個(gè)線程來處理這個(gè)請(qǐng)求攘蔽,同時(shí)在遠(yuǎn)程DNS服務(wù)器上啟動(dòng)一個(gè)DNS查詢,讓瀏覽器獲得請(qǐng)求對(duì)應(yīng)的IP地址呐粘。
2. TCP三次握手
瀏覽器與遠(yuǎn)程WEB服務(wù)器通過TCP三次握手來協(xié)商建立一個(gè)TCP/IP連接满俗。該握手包括一個(gè)同步報(bào)文,一個(gè)同步-應(yīng)答報(bào)文作岖,一個(gè)應(yīng)答報(bào)文唆垃。這三個(gè)報(bào)文在瀏覽器和服務(wù)器之間傳遞。該握手首先由客戶端嘗試建立通信痘儡,然后服務(wù)端響應(yīng)回答并接受客戶端的請(qǐng)求辕万,最后由客戶端發(fā)出該請(qǐng)求已經(jīng)被接受的報(bào)文。
ACK :ACK=1表示該報(bào)文段中有確認(rèn)號(hào)需要處理
SYN:SYN=1 ACK=0表明是建立連接請(qǐng)求報(bào)文段沉删,SYN=1ACK=1表明建立連接報(bào)文
FIN:FIN=1表示對(duì)端的數(shù)據(jù)已經(jīng)發(fā)送完畢渐尿,要求釋放連接
第一次握手:建立連接
客戶端發(fā)送鏈接請(qǐng)求報(bào)文段,將SYN值設(shè)為1矾瑰,Sequence Number設(shè)為x(客戶端初始化序列號(hào))砖茸。客戶端進(jìn)入SYN_SEND狀態(tài)殴穴,等待服務(wù)器的確認(rèn)凉夯。
第二次握手:服務(wù)器收到SYN報(bào)文段
服務(wù)器受到客戶端SYN報(bào)文段货葬,需要對(duì)這個(gè)SYN報(bào)文段進(jìn)行確認(rèn),設(shè)置Acknowledgemnt Number為x+1(Sequence Number+1,可以理解為告訴客戶端下一次發(fā)送報(bào)文的序列號(hào)從x+1開始)劲够。同時(shí)震桶,自己還要發(fā)送SYN請(qǐng)求信息,將SYN值設(shè)為1征绎,Sequence Number設(shè)為y(服務(wù)端的初始化序列號(hào))蹲姐。服務(wù)器端將上述所有信息放到一個(gè)報(bào)文段(即SYN+ACK報(bào)文段)中,一并發(fā)送到客戶端炒瘸,服務(wù)器進(jìn)入SYN_RECV狀態(tài)淤堵。
第三次握手:客戶端收到SYN+ACK報(bào)文段
客戶端收到服務(wù)器的SYN+ACK報(bào)文段后將Acknowledgment Number設(shè)置為y+1,向服務(wù)器發(fā)送ACK報(bào)文段顷扩,這個(gè)報(bào)文段發(fā)送完畢之后拐邪,客戶端和服務(wù)器都進(jìn)入ESTABLISGED狀態(tài),完成TCP三次握手隘截。
SYN-ACK重傳次數(shù):服務(wù)器發(fā)送完SYN-ACK包扎阶,如果未收到客戶確認(rèn)包,服務(wù)器進(jìn)行首次重傳婶芭,等待一段時(shí)間仍未收到客戶確認(rèn)包东臀,進(jìn)行第二次重傳,如果重傳粗疏超過系統(tǒng)規(guī)定的最大重傳粗疏犀农,系統(tǒng)將連接信息叢半連接隊(duì)列中刪除惰赋。注意,每次重傳等待的時(shí)間不一定相同呵哨。
半連接存活時(shí)間:是指半連接隊(duì)列的條目存活的最長(zhǎng)時(shí)間赁濒,也即服務(wù)從收到SYN包到確認(rèn)這個(gè)報(bào)文無效的最長(zhǎng)時(shí)間。改時(shí)間是所有重傳請(qǐng)求包的最長(zhǎng)等待時(shí)間總和孟害。有時(shí)我們也稱半連接存活時(shí)間為Timeout時(shí)間拒炎、SYN_RECV存活時(shí)間。
3.服務(wù)器響應(yīng)200
TCP/IP連接建立后击你,瀏覽器向通過該連接向遠(yuǎn)程服務(wù)器發(fā)送HTTP的GET請(qǐng)求,遠(yuǎn)程服務(wù)器找到資源并使用HTTP響應(yīng)返回該資源谎柄,值為200的HTTP響應(yīng)狀態(tài)表示一個(gè)正確的響應(yīng)
4.生成Render Tree
客戶端下載完資源后丁侄,便進(jìn)入了我們關(guān)注的前端模塊了。瀏覽器會(huì)解析HTML成樹形的數(shù)據(jù)結(jié)構(gòu)DOM朝巫,生成DOM Tree鸿摇,瀏覽器將css代碼解析成樹形的數(shù)據(jù)結(jié)構(gòu)CSSOM,生成CSS Rule Tree捍歪。
DOM和CSSOM都是以Bytes->charcters->tokens->nodes->object model這樣的方式生成最終的數(shù)據(jù)户辱。DOM樹的生成過程是一個(gè)深度遍歷過程:當(dāng)前節(jié)點(diǎn)的所有節(jié)點(diǎn)都構(gòu)建好之后才回去構(gòu)建當(dāng)前節(jié)點(diǎn)的下一個(gè)兄弟節(jié)點(diǎn)。
DOM Tree和CSS Rule Tree結(jié)合生成Render Tree
display:none的節(jié)點(diǎn)不會(huì)被加入Render Tree 而 visibilit:hidden則會(huì)
display:隱藏對(duì)應(yīng)的元素但不會(huì)擠占元素原來的空間
visibility:隱藏對(duì)應(yīng)的元素并且擠占元素原來的空間
所以糙臼,如果某個(gè)節(jié)點(diǎn)最開始是不顯示的庐镐,設(shè)為 display:none是最好的
5.渲染頁(yè)面
布局
有了Render Tree,瀏覽器知道網(wǎng)頁(yè)中有哪些節(jié)點(diǎn)变逃、各個(gè)節(jié)點(diǎn)的css定義以及他們的從屬關(guān)系必逆。接著就開始布局,計(jì)算出每個(gè)節(jié)點(diǎn)在屏幕中的位置
渲染
瀏覽器在知道了哪些節(jié)點(diǎn)要展示揽乱,并且每個(gè)節(jié)點(diǎn)的css屬性是什么名眉、每個(gè)節(jié)點(diǎn)在屏幕中的位置在哪里的時(shí)候,就會(huì)進(jìn)入了最后一步凰棉,按照算出來的規(guī)則损拢,通過顯卡,把內(nèi)容畫到屏幕上撒犀。
但是javascript可以根據(jù)DOM API操作DOM福压。比如JS修改了DOM或者CSS屬性,也會(huì)重新的觸發(fā)布局和渲染的執(zhí)行過程或舞。
補(bǔ)充:TCP四處揮手
第一次揮手:客戶端想分手
假設(shè)客戶端想關(guān)閉連接荆姆,客戶端會(huì)發(fā)送一個(gè)FIN標(biāo)志位置為1的包(FIN=1,clientseq=x),表示自己已經(jīng)沒有數(shù)據(jù)可以發(fā)送了映凳,但是可以接受數(shù)據(jù)胆筒,進(jìn)入FIN_WAIT_1狀態(tài)
第二次揮手:服務(wù)器也想分手
服務(wù)器端確認(rèn)客戶端的FIN包,發(fā)送一個(gè)確認(rèn)包(ACK=1,ACknum=clientseq+1),表示自己已經(jīng)接收到了客戶端關(guān)閉連接的請(qǐng)求名單上還沒有準(zhǔn)備好關(guān)閉連接诈豌。發(fā)送包后仆救,服務(wù)器進(jìn)入CLOSE_WAIT狀態(tài),客戶端收到確認(rèn)包后队询,進(jìn)入FIN_WAIT_2狀態(tài)派桩,等待服務(wù)器關(guān)閉連接
第三次揮手:服務(wù)器準(zhǔn)備好分手
服務(wù)器準(zhǔn)備好關(guān)閉連接后,像客戶端發(fā)送結(jié)束請(qǐng)求蚌斩,F(xiàn)IN置為1铆惑,(FIN=1,serverseq=y),發(fā)送完畢后進(jìn)入LAST_ACK狀態(tài)送膳,等待客戶端的最后一個(gè)ACK
第四次揮手:分手
客戶端接受來自服務(wù)器端的請(qǐng)求后员魏,發(fā)送一個(gè)確認(rèn)包(ACK=1,ACKnum=serverseq+1)進(jìn)入TIME_WAIT狀態(tài)叠聋,等待可能出現(xiàn)的要求重傳的ACK包撕阎。
服務(wù)器端接受到這個(gè)確認(rèn)包之后,關(guān)閉連接碌补,進(jìn)入CLOSED狀態(tài)虏束。
客戶端等待2MSL之后棉饶,沒有收到回復(fù),確保服務(wù)器端確實(shí)為關(guān)閉了镇匀,客戶端也關(guān)閉連接照藻,進(jìn)入CLOSED狀態(tài)。