從輸入地址到顯示頁(yè)面的過(guò)程,大致可以分成兩個(gè)部分:
第一部分:用戶輸入在瀏覽器地址欄輸入U(xiǎn)RL → 到客戶端(瀏覽器)拿到服務(wù)端(服務(wù)器)的數(shù)據(jù)
第二部分:瀏覽器拿到數(shù)據(jù)后 → 渲染呈現(xiàn)頁(yè)面給用戶(瀏覽器工作過(guò)程)
例如:
第一部分:
第一步: 輸入網(wǎng)址http://www.itdecent.cn/p/8f050df1961d

可以把URL分成協(xié)議、網(wǎng)絡(luò)地址、資源路徑三部分。
- 協(xié)議:從該計(jì)算機(jī)獲取資源的方式,有HTTP、HTTPS、FTP等,不同協(xié)議有不同的通訊內(nèi)容格式。
- 網(wǎng)絡(luò)地址:指連接網(wǎng)絡(luò)上的哪一臺(tái)計(jì)算機(jī),可以是域名、IP地址,可以包括端口號(hào)。如:“www.itdecent.cn”、“192.168.0.91:8080”。
- 資源路徑:指從服務(wù)器上獲取哪一項(xiàng)資源。如 “/p/8f050df1961d” 。
第二步:通過(guò)DNS解析獲得網(wǎng)址對(duì)應(yīng)的IP地址
- 瀏覽器緩存 – 瀏覽器會(huì)緩存DNS記錄一段時(shí)間。 有趣的是,操作系統(tǒng)沒(méi)有告訴瀏覽器儲(chǔ)存DNS記錄的時(shí)間,這樣不同瀏覽器會(huì)儲(chǔ)存?zhèn)€自固定的一個(gè)時(shí)間(2分鐘到30分鐘不等)。
- 系統(tǒng)緩存 – 如果在瀏覽器緩存里沒(méi)有找到需要的記錄,瀏覽器會(huì)做一個(gè)系統(tǒng)調(diào)用(windows里是gethostbyname)。這樣便可獲得系統(tǒng)緩存中的記錄。
- 路由器緩存 – 接著,前面的查詢請(qǐng)求發(fā)向路由器,它一般會(huì)有自己的DNS緩存。
- ISP DNS 緩存 – 接下來(lái)要check的就是ISP緩存DNS的服務(wù)器。在這一般都能找到相應(yīng)的緩存記錄。
- 遞歸搜索 – 你的ISP的DNS服務(wù)器從跟域名服務(wù)器開(kāi)始進(jìn)行遞歸搜索,從.com頂級(jí)域名服務(wù)器到Facebook的域名服務(wù)器。一般DNS服務(wù)器的緩存中會(huì)有.com域名服務(wù)器中的域名,所以到頂級(jí)服務(wù)器的匹配過(guò)程不是那么必要了。
DNS中遞歸查詢和迭代查詢的區(qū)別:
1、 遞歸查詢: 一般客戶機(jī)和服務(wù)器之間屬遞歸查詢,即當(dāng)客戶機(jī)向DNS服務(wù)器發(fā)出請(qǐng)求后,若DNS服務(wù)器本身不能解析,則會(huì)向另外的DNS服務(wù)器發(fā)出查詢請(qǐng)求,得到結(jié)果后轉(zhuǎn)交客戶機(jī)。
2、 迭代查詢(反復(fù)查詢): 一般DNS服務(wù)器之間屬迭代查詢,如:若DNS2不能響應(yīng)DNS1的請(qǐng)求,則它會(huì)將DNS3的IP給DNS2,以便其再向DNS3發(fā)出請(qǐng)求。
以一個(gè)DNS請(qǐng)求解析為例:
1)用戶發(fā)起域名請(qǐng)求到dnsA,這時(shí)dnsA有這個(gè)記錄,將結(jié)果返回給用戶,這個(gè)過(guò)程是遞歸查詢。
2)用戶發(fā)起域名請(qǐng)求到dnsA,這時(shí)dns沒(méi)有這個(gè)記錄,它去向dnsB問(wèn)有沒(méi)有這個(gè)記錄,以此類(lèi)推,直到把結(jié)果返回給用戶,這個(gè)過(guò)程是遞歸查詢。
3)用戶發(fā)起域名請(qǐng)求到dnsA,這時(shí)dnsA沒(méi)有這個(gè)記錄,它告訴用戶,我沒(méi)有這個(gè)記錄,你去問(wèn)dnsB吧,這個(gè)過(guò)程是迭代查詢。
第三步:瀏覽器與遠(yuǎn)程web服務(wù)器 通過(guò)TCP三次握手協(xié)商來(lái)建立一個(gè) TCP/IP 連接
在通過(guò)DNS域名解析后,獲取到了服務(wù)器的IP地址,在獲取到IP地址后,便會(huì)開(kāi)始建立一次連接,這是由TCP協(xié)議完成的,主要通過(guò)三次握手進(jìn)行連接。
- 第一次握手: 建立連接時(shí),客戶端發(fā)送SYN(synchronize)包(syn=j)到服務(wù)器,并進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器確認(rèn);
- 第二次握手: 服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(syn=k),即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);
- 第三次握手: 客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED(TCP連接成功)狀態(tài),完成三次握手。
- 完成三次握手,客戶端與服務(wù)器開(kāi)始傳送數(shù)據(jù)。
在這個(gè)過(guò)程中,如果發(fā)送端在規(guī)定延遲時(shí)間內(nèi)沒(méi)有收到回復(fù)則默認(rèn)接收方?jīng)]有收到請(qǐng)求,而再次發(fā)送,直到收到回復(fù)為止。

第四步:瀏覽器 通過(guò)TCP/IP連接 向web服務(wù)器 發(fā)送一個(gè) HTTP 請(qǐng)求
HTTP請(qǐng)求包括請(qǐng)求報(bào)頭和請(qǐng)求主體兩個(gè)部分,其中請(qǐng)求報(bào)頭包含了至關(guān)重要的信息,包括請(qǐng)求的方法(GET / POST)、目標(biāo)url、遵循的協(xié)議(http / https / ftp…),返回的信息是否需要緩存,以及客戶端是否發(fā)送cookie等。
第五步:服務(wù)器響應(yīng)請(qǐng)求
服務(wù)接收到客戶端發(fā)送的HTTP請(qǐng)求后,查找客戶端請(qǐng)求的資源,并返回響應(yīng)報(bào)文,響應(yīng)報(bào)文中包括一個(gè)重要的信息——狀態(tài)碼。狀態(tài)碼由三位數(shù)字組成。
常見(jiàn)的狀態(tài)碼
1xx 【消息】服務(wù)器收到請(qǐng)求,需要請(qǐng)求者繼續(xù)執(zhí)行操作
2xx 【成功】請(qǐng)求已成功被服務(wù)器接收、理解、并接受。
3xx 【重定向】客戶端需要采取進(jìn)一步的操作以完成請(qǐng)求
4xx 【客戶端請(qǐng)求錯(cuò)誤】客戶端錯(cuò)誤,請(qǐng)求包含語(yǔ)法錯(cuò)誤或無(wú)法完成請(qǐng)求
5xx 【服務(wù)器錯(cuò)誤】服務(wù)器在處理請(qǐng)求的過(guò)程中發(fā)生了錯(cuò)誤
常見(jiàn)的有:
200 OK //客戶端請(qǐng)求成功
304 Not Modified // 未修改。所請(qǐng)求的資源未修改,服務(wù)器返回此狀態(tài)碼時(shí),不會(huì)返回任何資源
400 Bad Request //客戶端請(qǐng)求有語(yǔ)法錯(cuò)誤,不能被服務(wù)器所理解
401 Unauthorized // 當(dāng)前請(qǐng)求要求用戶的身份認(rèn)證
403 Forbidden // 服務(wù)器理解請(qǐng)求客戶端的請(qǐng)求,但是拒絕執(zhí)行此請(qǐng)求
404 Not Found //請(qǐng)求資源不存在,輸入了錯(cuò)誤的URL
500 Internal Server Error //服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤
503 Server Unavailable // 由于超載或系統(tǒng)維護(hù),服務(wù)器暫時(shí)的無(wú)法處理客戶端的請(qǐng)求。一段時(shí)間后可能恢復(fù)正常
第六步:服務(wù)器返回相應(yīng)文件
請(qǐng)求成功后,服務(wù)器會(huì)返回相應(yīng)的HTML文件。接下來(lái)就到了頁(yè)面的渲染階段了。
第二部分:
第七步:頁(yè)面渲染
整個(gè)過(guò)程涉及兩個(gè)方面:解析和渲染。在渲染頁(yè)面之前,需要構(gòu)建DOM樹(shù)和CSSOM樹(shù)。


在瀏覽器還沒(méi)接收到完整的 HTML 文件時(shí),它就開(kāi)始渲染頁(yè)面了,在遇到外部鏈入的腳本標(biāo)簽或樣式標(biāo)簽或圖片時(shí),會(huì)再次發(fā)送 HTTP 請(qǐng)求重復(fù)上述的步驟。在收到 CSS 文件后會(huì)對(duì)已經(jīng)渲染的頁(yè)面重新渲染,加入它們應(yīng)有的樣式,圖片文件加載完立刻顯示在相應(yīng)位置。在這一過(guò)程中可能會(huì)觸發(fā)頁(yè)面的重繪或重排。這里就涉及了兩個(gè)重要概念:Reflow和Repaint。
Reflow,也稱作Layout,中文叫回流,一般意味著元素的內(nèi)容、結(jié)構(gòu)、位置或尺寸發(fā)生了變化,需要重新計(jì)算樣式和渲染樹(shù),這個(gè)過(guò)程稱為Reflow。
Repaint,中文重繪,意味著元素發(fā)生的改變只是影響了元素的一些外觀之類(lèi)的時(shí)候(例如,背景色,邊框顏色,文字顏色等),此時(shí)只需要應(yīng)用新樣式繪制這個(gè)元素就OK了,這個(gè)過(guò)程稱為Repaint。
所以說(shuō)Reflow的成本比Repaint的成本高得多的多。DOM樹(shù)里的每個(gè)結(jié)點(diǎn)都會(huì)有reflow方法,一個(gè)結(jié)點(diǎn)的reflow很有可能導(dǎo)致子結(jié)點(diǎn),甚至父點(diǎn)以及同級(jí)結(jié)點(diǎn)的reflow。
下面這些動(dòng)作有很大可能會(huì)是成本比較高的:
- 增加、刪除、修改DOM結(jié)點(diǎn)時(shí),會(huì)導(dǎo)致Reflow或Repaint
- 移動(dòng)DOM的位置,或是搞個(gè)動(dòng)畫(huà)的時(shí)候
- 內(nèi)容發(fā)生變化
- 修改CSS樣式的時(shí)候
- Resize窗口的時(shí)候(移動(dòng)端沒(méi)有這個(gè)問(wèn)題),或是滾動(dòng)的時(shí)候
- 修改網(wǎng)頁(yè)的默認(rèn)字體時(shí)
- 基本上來(lái)說(shuō),reflow有如下的幾個(gè)原因:
- Initial,網(wǎng)頁(yè)初始化的時(shí)候
- Incremental,一些js在操作DOM樹(shù)時(shí)
- Resize,其些元件的尺寸變了
- StyleChange,如果CSS的屬性發(fā)生變化了
- Dirty,幾個(gè)Incremental的reflow發(fā)生在同一個(gè)frame的子樹(shù)上
第八步:關(guān)閉TCP連接(四次揮手)或者繼續(xù)保持鏈接

第一次揮手是瀏覽器發(fā)完數(shù)據(jù)后,發(fā)送FIN請(qǐng)求斷開(kāi)連接。
第二次揮手是服務(wù)器發(fā)送ACK表示同意,如果在這一次服務(wù)器也發(fā)送FIN請(qǐng)求斷開(kāi)連接似乎也沒(méi)有不妥,但考慮到服務(wù)器可能還有數(shù)據(jù)要發(fā)送,所以服務(wù)器發(fā)送FIN應(yīng)該放在第三次揮手中。
這樣瀏覽器需要返回ACK表示同意,也就是第四次揮手。
瀏覽器內(nèi)核——廠商前綴——代表瀏覽器——內(nèi)核背景
- Triden -ms- IE瀏覽器系列 該內(nèi)核程序在1997年的IE4中首次被采用,是微軟在Mosaic代碼的基礎(chǔ)之上修改而來(lái)的,并沿用到IE11,也被普遍稱作”IE內(nèi)核”。Trident實(shí)際上是一款開(kāi)放的內(nèi)核,其接口內(nèi)核設(shè)計(jì)的相當(dāng)成熟,因此才有許多采用IE內(nèi)核而非IE的瀏覽器(殼瀏覽器)涌現(xiàn)。
- Gecko -moz-Firefox Netscape6開(kāi)始采用的內(nèi)核,后來(lái)的Mozilla FireFox(火狐瀏覽器)也采用了該內(nèi)核,Gecko的特點(diǎn)是代碼完全公開(kāi)
- Webkit -webkit- Safari內(nèi)核,Chrome內(nèi)核原型,開(kāi)源,包含了來(lái)自KDE項(xiàng)目和蘋(píng)果公司的一些組件,主要用于Mac OS系統(tǒng),它的特點(diǎn)在于源碼解構(gòu)清晰、渲染速度極快,缺點(diǎn)是網(wǎng)頁(yè)代碼的兼容性不高,導(dǎo)致一些編寫(xiě)不標(biāo)準(zhǔn)的網(wǎng)頁(yè)無(wú)法正常顯示
- Blink -webkit- Chrome、opera等除IE、Firefox、Safari之外的幾乎- 所有瀏覽器(幾乎所有國(guó)產(chǎn)雙內(nèi)核瀏覽器(Trident/Blink)如360、獵豹、qq、百度等) Blink是一個(gè)由Google和Opera Software開(kāi)發(fā)的瀏覽器排版引擎,是基于Webkit內(nèi)核的子項(xiàng)目