轉(zhuǎn)載:https://juejin.cn/post/6844903987670417422
前言
打開瀏覽器從輸入網(wǎng)址到網(wǎng)頁呈現(xiàn)在大家面前,背后到底發(fā)生了什么?經(jīng)歷怎么樣的一個(gè)過程?先給大家來張總體流程圖,具體步驟請(qǐng)看下文分解!寫文章不易,請(qǐng)多多支持與關(guān)注!
總體來說分為以下幾個(gè)過程:
DNS 解析:將域名解析成 IP 地址
TCP 連接:TCP 三次握手
發(fā)送 HTTP 請(qǐng)求
服務(wù)器處理請(qǐng)求并返回 HTTP 報(bào)文
瀏覽器解析渲染頁面
斷開連接:TCP 四次揮手
具體過程
URL 到底是啥
URL(Uniform Resource Locator),統(tǒng)一資源定位符,用于定位互聯(lián)網(wǎng)上資源,俗稱網(wǎng)址。 比如http://www.w3school.com.cn/html/index.asp,遵守以下的語法規(guī)則:
scheme://host.domain:port/path/filename各部分解釋如下:
scheme:定義因特網(wǎng)服務(wù)的類型。常見的協(xié)議有 http、https、ftp、file,其中最常見的類型是 http,而 https 則是進(jìn)行加密的網(wǎng)絡(luò)傳輸。
host:定義域主機(jī)(http 的默認(rèn)主機(jī)是 www)
domain:定義因特網(wǎng)域名,比如 w3school.com.cn
port:定義主機(jī)上的端口號(hào)(http 的默認(rèn)端口號(hào)是 80)
path:定義服務(wù)器上的路徑(如果省略,則文檔必須位于網(wǎng)站的根目錄中)
filename:定義文檔/資源的名稱
域名解析(DNS)
在瀏覽器輸入網(wǎng)址后,首先要經(jīng)過域名解析,因?yàn)闉g覽器并不能直接通過域名找到對(duì)應(yīng)的服務(wù)器,而是要通過 IP 地址。大家這里或許會(huì)有個(gè)疑問----計(jì)算機(jī)既可以被賦予 IP 地址,也可以被賦予主機(jī)名和域名。比如www.hackr.jp。那怎么不一開始就賦予個(gè) IP 地址?這樣就可以省去解析麻煩。我們先來了解下什么是 IP 地址
IP 地址
IP 地址是指互聯(lián)網(wǎng)協(xié)議地址,是 IP Address 的縮寫。IP 地址是 IP 協(xié)議提供的一種統(tǒng)一的地址格式,它為互聯(lián)網(wǎng)上的每一個(gè)網(wǎng)絡(luò)和每一臺(tái)主機(jī)分配一個(gè)邏輯地址,以此來屏蔽物理地址的差異。IP 地址是一個(gè) 32 位的二進(jìn)制數(shù),比如 127.0.0.1 為本機(jī) IP。域名就相當(dāng)于 IP 地址喬裝打扮的偽裝者,帶著一副面具。它的作用就是便于記憶和溝通的一組服務(wù)器的地址。用戶通常使用主機(jī)名或域名來訪問對(duì)方的計(jì)算機(jī),而不是直接通過 IP 地址訪問。因?yàn)榕c IP 地址的一組純數(shù)字相比,用字母配合數(shù)字的表示形式來指定計(jì)算機(jī)名更符合人類的記憶習(xí)慣。但要讓計(jì)算機(jī)去理解名稱,相對(duì)而言就變得困難了。因?yàn)橛?jì)算機(jī)更擅長(zhǎng)處理一長(zhǎng)串?dāng)?shù)字。為了解決上述的問題,DNS 服務(wù)應(yīng)運(yùn)而生。
什么是域名解析
DNS 協(xié)議提供通過域名查找 IP 地址,或逆向從 IP 地址反查域名的服務(wù)。DNS 是一個(gè)網(wǎng)絡(luò)服務(wù)器,我們的域名解析簡(jiǎn)單來說就是在 DNS 上記錄一條信息記錄。
例如 baidu.com220.114.23.56(服務(wù)器外網(wǎng)IP地址)80(服務(wù)器端口號(hào))復(fù)制代碼
域名解析過程
上述圖片是查找www.google.com的IP地址過程。
首先在本地域名服務(wù)器中查詢IP地址,如果沒有找到的情況下,本地域名服務(wù)器會(huì)向根域名服務(wù)器發(fā)送一個(gè)請(qǐng)求,如果根域名服務(wù)器也不存在該域名時(shí),本地域名會(huì)向com頂級(jí)域名服務(wù)器發(fā)送一個(gè)請(qǐng)求,依次類推下去。直到最后本地域名服務(wù)器得到google的IP地址并把它緩存到本地,供下次查詢使用。從上述過程中,可以看出網(wǎng)址的解析是一個(gè)從右向左的過程:com -> google.com -> www.google.com。但是你是否發(fā)現(xiàn)少了點(diǎn)什么,根域名服務(wù)器的解析過程呢?事實(shí)上,真正的網(wǎng)址是www.google.com.,并不是我多打了一個(gè).,這個(gè).對(duì)應(yīng)的就是根域名服務(wù)器,默認(rèn)情況下所有的網(wǎng)址的最后一位都是.,既然是默認(rèn)情況下,為了方便用戶,通常都會(huì)省略,瀏覽器在請(qǐng)求DNS的時(shí)候會(huì)自動(dòng)加上,所有網(wǎng)址真正的解析過程為:. -> .com -> google.com. -> www.google.com.。
DNS優(yōu)化
了解了DNS的過程,可以為我們帶來哪些?上文中請(qǐng)求到google的IP地址時(shí),經(jīng)歷了8個(gè)步驟,這個(gè)過程中存在多個(gè)請(qǐng)求(同時(shí)存在UDP和TCP請(qǐng)求,為什么有兩種請(qǐng)求方式,請(qǐng)自行查找)。如果每次都經(jīng)過這么多步驟,是否太耗時(shí)間?如何減少該過程的步驟呢?那就是DNS緩存。
DNS緩存
DNS存在著多級(jí)緩存,從離瀏覽器的距離排序的話,有以下幾種:瀏覽器緩存,操作系統(tǒng)緩存,路由器緩存,ISP服務(wù)器緩存,根域名服務(wù)器緩存,頂級(jí)域名服務(wù)器緩存,主域名服務(wù)器緩存。
瀏覽器緩存:瀏覽器會(huì)按照一定的頻率緩存 DNS 記錄。
操作系統(tǒng)緩存:如果瀏覽器緩存中找不到需要的 DNS 記錄,那就去操作系統(tǒng)中找。
路由器緩存:路由器也有 DNS 緩存。
ISP服務(wù)器緩存:ISP 是互聯(lián)網(wǎng)服務(wù)提供商(Internet Service Provider)的簡(jiǎn)稱,ISP 有專門的 DNS 服務(wù)器應(yīng)對(duì) DNS 查詢請(qǐng)求。
根域名服務(wù)器緩存:ISP 的 DNS 服務(wù)器還找不到的話,它就會(huì)向根域名服務(wù)器發(fā)出請(qǐng)求,進(jìn)行遞歸查詢(DNS 服務(wù)器先問根域名服務(wù)器.com 域名服務(wù)器的 IP 地址,然后再問.baidu 域名服務(wù)器,依次類推)
在你的chrome瀏覽器中輸入chrome://net-internals/#dns,你可以看到chrome瀏覽器的DNS緩存。
操作系統(tǒng)緩存主要存在/etc/hosts(Linux系統(tǒng))中
DNS負(fù)載均衡
不知道大家有沒有思考過一個(gè)問題:
DNS返回的IP地址是否每次都一樣?如果每次都一樣是否說明你請(qǐng)求的資源都位于同一臺(tái)機(jī)器上面,那么這臺(tái)機(jī)器需要多高的性能和儲(chǔ)存才能滿足億萬請(qǐng)求呢?其實(shí)真實(shí)的互聯(lián)網(wǎng)世界背后存在成千上百臺(tái)服務(wù)器,大型的網(wǎng)站甚至更多。但是在用戶的眼中,它需要的只是處理他的請(qǐng)求,哪臺(tái)機(jī)器處理請(qǐng)求并不重要。DNS可以返回一個(gè)合適的機(jī)器的IP給用戶,例如可以根據(jù)每臺(tái)機(jī)器的負(fù)載量,該機(jī)器離用戶地理位置的距離等等,這種過程就是DNS負(fù)載均衡,又叫做DNS重定向。大家耳熟能詳?shù)腃DN(Content Delivery Network)就是利用DNS的重定向技術(shù),DNS服務(wù)器會(huì)返回一個(gè)跟用戶最接近的點(diǎn)的IP地址給用戶,CDN節(jié)點(diǎn)的服務(wù)器負(fù)責(zé)響應(yīng)用戶的請(qǐng)求,提供所需的內(nèi)容。
小結(jié)
瀏覽器通過向 DNS 服務(wù)器發(fā)送域名,DNS 服務(wù)器查詢到與域名相對(duì)應(yīng)的 IP 地址,然后返回給瀏覽器,瀏覽器再將 IP 地址打在協(xié)議上,同時(shí)請(qǐng)求參數(shù)也會(huì)在協(xié)議搭載,然后一并發(fā)送給對(duì)應(yīng)的服務(wù)器。接下來介紹向服務(wù)器發(fā)送 HTTP 請(qǐng)求階段,HTTP 請(qǐng)求分為三個(gè)部分:TCP 三次握手、http 請(qǐng)求響應(yīng)信息、關(guān)閉 TCP 連接。
TCP 三次握手
在客戶端發(fā)送數(shù)據(jù)之前會(huì)發(fā)起 TCP 三次握手用以同步客戶端和服務(wù)端的序列號(hào)和確認(rèn)號(hào),并交換 TCP 窗口大小信息。
TCP 三次握手的過程如下:
客戶端發(fā)送一個(gè)帶 SYN=1,Seq=X 的數(shù)據(jù)包到服務(wù)器端口(第一次握手,由瀏覽器發(fā)起,告訴服務(wù)器我要發(fā)送請(qǐng)求了)
服務(wù)器發(fā)回一個(gè)帶 SYN=1, ACK=X+1, Seq=Y 的響應(yīng)包以示傳達(dá)確認(rèn)信息(第二次握手,由服務(wù)器發(fā)起,告訴瀏覽器我準(zhǔn)備接受了,你趕緊發(fā)送吧)
客戶端再回傳一個(gè)帶 ACK=Y+1, Seq=Z 的數(shù)據(jù)包,代表“握手結(jié)束”(第三次握手,由瀏覽器發(fā)送,告訴服務(wù)器,我馬上就發(fā)了,準(zhǔn)備接受吧)
為啥需要三次握手
為了防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到了服務(wù)端,因而產(chǎn)生錯(cuò)誤
發(fā)送 HTTP 請(qǐng)求
TCP 三次握手結(jié)束后,開始發(fā)送 HTTP 請(qǐng)求報(bào)文。
其實(shí)這部分又可以稱為前端工程師眼中的HTTP,它主要發(fā)生在客戶端。發(fā)送HTTP請(qǐng)求的過程就是構(gòu)建HTTP請(qǐng)求報(bào)文并通過TCP協(xié)議發(fā)送到服務(wù)器指定端口(HTTP協(xié)議80/8080, HTTPS協(xié)議443)。
請(qǐng)求報(bào)文由請(qǐng)求行(request line)、請(qǐng)求頭(header)、請(qǐng)求空行(blank line)、請(qǐng)求體四個(gè)部分組成,如下圖所示:
請(qǐng)求行包含請(qǐng)求方法、URL、協(xié)議版本請(qǐng)求方法包含 8 種:GET、POST、PUT、DELETE、CONNECT、HEAD、OPTIONS、TRACE
URL 即請(qǐng)求地址,由 <協(xié)議>://<主機(jī)>:<端口>/<路徑>?<參數(shù)> 組成
協(xié)議版本即 http 版本號(hào)
POST? /chapter17/user.html HTTP/1.1
以上代碼中“POST”代表請(qǐng)求方法,“/chapter17/user.html”表示 URL,“HTTP/1.1”代表協(xié)議和協(xié)議的版本。現(xiàn)在比較流行的是 Http1.1 版本
請(qǐng)求頭包含請(qǐng)求的附加信息,由關(guān)鍵字/值對(duì)組成,每行一對(duì),關(guān)鍵字和值用英文冒號(hào)“:”分隔。
請(qǐng)求頭部通知服務(wù)器有關(guān)于客戶端請(qǐng)求的信息。它包含許多有關(guān)的客戶端環(huán)境和請(qǐng)求正文的有用信息。其中比如:Host,表示主機(jī)名,虛擬主機(jī);Connection,HTTP/1.1 增加的,使用 keepalive,即持久連接,一個(gè)連接可以發(fā)多個(gè)請(qǐng)求;User-Agent,請(qǐng)求發(fā)出者,兼容性以及定制化需求。
請(qǐng)求報(bào)頭允許客戶端向服務(wù)器傳遞請(qǐng)求的附加信息和客戶端自身的信息。PS: 客戶端不一定特指瀏覽器,有時(shí)候也可使用Linux下的CURL命令以及HTTP客戶端測(cè)試工具等。常見的請(qǐng)求報(bào)頭有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等。上圖是使用Chrome開發(fā)者工具截取的對(duì)百度的HTTP請(qǐng)求以及響應(yīng)報(bào)文,從圖中可以看出,請(qǐng)求報(bào)頭中使用了Accept, Accept-Encoding, Accept-Language, Cache-Control, Connection, Cookie等字段。Accept用于指定客戶端用于接受哪些類型的信息,Accept-Encoding與Accept類似,它用于指定接受的編碼方式。Connection設(shè)置為Keep-alive用于告訴客戶端本次HTTP請(qǐng)求結(jié)束之后并不需要關(guān)閉TCP連接,這樣可以使下次HTTP請(qǐng)求使用相同的TCP通道,節(jié)省TCP連接建立的時(shí)間。
請(qǐng)求體,可以承載多個(gè)請(qǐng)求參數(shù)的數(shù)據(jù),包含回車符、換行符和請(qǐng)求數(shù)據(jù),并不是所有請(qǐng)求都具有請(qǐng)求數(shù)據(jù)。
當(dāng)使用POST, PUT等方法時(shí),通常需要客戶端向服務(wù)器傳遞數(shù)據(jù)。這些數(shù)據(jù)就儲(chǔ)存在請(qǐng)求正文中。在請(qǐng)求頭中有一些與請(qǐng)求正文相關(guān)的信息,例如: 現(xiàn)在的Web應(yīng)用通常采用Rest架構(gòu),請(qǐng)求的數(shù)據(jù)格式一般為json。這時(shí)就需要設(shè)置Content-Type: application/json。
上面代碼,承載著 name、password、realName 三個(gè)請(qǐng)求參數(shù)。
服務(wù)器處理請(qǐng)求并返回 HTTP 報(bào)文
服務(wù)器
服務(wù)器是網(wǎng)絡(luò)環(huán)境中的高性能計(jì)算機(jī),它偵聽網(wǎng)絡(luò)上的其他計(jì)算機(jī)(客戶機(jī))提交的服務(wù)請(qǐng)求,并提供相應(yīng)的服務(wù),比如網(wǎng)頁服務(wù)、文件下載服務(wù)、郵件服務(wù)、視頻服務(wù)。而客戶端主要的功能是瀏覽網(wǎng)頁、看視頻、聽音樂等等,兩者截然不同。 每臺(tái)服務(wù)器上都會(huì)安裝處理請(qǐng)求的應(yīng)用——web server。常見的 web server 產(chǎn)品有 apache、nginx、IIS 或 Lighttpd 等。web server 擔(dān)任管控的角色,對(duì)于不同用戶發(fā)送的請(qǐng)求,會(huì)結(jié)合配置文件,把不同請(qǐng)求委托給服務(wù)器上處理相應(yīng)請(qǐng)求的程序進(jìn)行處理(例如 CGI 腳本,JSP 腳本,servlets,ASP 腳本,服務(wù)器端 JavaScript,或者一些其它的服務(wù)器端技術(shù)等),然后返回后臺(tái)程序處理產(chǎn)生的結(jié)果作為響應(yīng)。MVC 后臺(tái)處理階段
后臺(tái)開發(fā)現(xiàn)在有很多框架,但大部分都還是按照 MVC 設(shè)計(jì)模式進(jìn)行搭建的。 MVC 是一個(gè)設(shè)計(jì)模式,將應(yīng)用程序分成三個(gè)核心部件:模型(model)-- 視圖(view)--控制器(controller),它們各自處理自己的任務(wù),實(shí)現(xiàn)輸入、處理和輸出的分離。視圖(view)
它是提供給用戶的操作界面,是程序的外殼。
模型(model)
模型主要負(fù)責(zé)數(shù)據(jù)交互。在 MVC 的三個(gè)部件中,模型擁有最多的處理任務(wù)。一個(gè)模型能為多個(gè)視圖提供數(shù)據(jù)。
控制器(controller)
它負(fù)責(zé)根據(jù)用戶從"視圖層"輸入的指令,選取"模型層"中的數(shù)據(jù),然后對(duì)其進(jìn)行相應(yīng)的操作,產(chǎn)生最終結(jié)果。控制器屬于管理者角色,從視圖接收請(qǐng)求并決定調(diào)用哪個(gè)模型構(gòu)件去處理請(qǐng)求,然后再確定用哪個(gè)視圖來顯示模型處理返回的數(shù)據(jù)。這三層是緊密聯(lián)系在一起的,但又是互相獨(dú)立的,每一層內(nèi)部的變化不影響其他層。每一層都對(duì)外提供接口(Interface),供上面一層調(diào)用。至于這一階段發(fā)生什么?簡(jiǎn)而言之,首先瀏覽器發(fā)送過來的請(qǐng)求先經(jīng)過控制器,控制器進(jìn)行邏輯處理和請(qǐng)求分發(fā),接著會(huì)調(diào)用模型,這一階段模型會(huì)獲取 redis db 以及 MySQL 的數(shù)據(jù),獲取數(shù)據(jù)后將渲染好的頁面,響應(yīng)信息會(huì)以響應(yīng)報(bào)文的形式返回給客戶端,最后瀏覽器通過渲染引擎將網(wǎng)頁呈現(xiàn)在用戶面前。
http 響應(yīng)報(bào)文
自然而然這部分對(duì)應(yīng)的就是后端工程師眼中的HTTP。后端從在固定的端口接收到TCP報(bào)文開始,這一部分對(duì)應(yīng)于編程語言中的socket。它會(huì)對(duì)TCP連接進(jìn)行處理,對(duì)HTTP協(xié)議進(jìn)行解析,并按照?qǐng)?bào)文格式進(jìn)一步封裝成HTTP Request對(duì)象,供上層使用。這一部分工作一般是由Web服務(wù)器去進(jìn)行,我使用過的Web服務(wù)器有Tomcat, Jetty和Netty等等。
響應(yīng)報(bào)文由響應(yīng)行(request line)、響應(yīng)頭部(header)、響應(yīng)主體三個(gè)部分組成。如下圖所示:響應(yīng)行包含:協(xié)議版本,狀態(tài)碼,狀態(tài)碼描述
http狀態(tài)碼
分類分類描述
1**信息,服務(wù)器收到請(qǐng)求,需要請(qǐng)求者繼續(xù)執(zhí)行操作
2**成功,操作被成功接收并處理
3**重定向,需要進(jìn)一步的操作以完成請(qǐng)求
4**客戶端錯(cuò)誤,請(qǐng)求包含語法錯(cuò)誤或無法完成請(qǐng)求
5**服務(wù)器錯(cuò)誤,服務(wù)器在處理請(qǐng)求的過程中發(fā)生了錯(cuò)誤
響應(yīng)頭部包含響應(yīng)報(bào)文的附加信息,由 名/值 對(duì)組成
常見的響應(yīng)報(bào)頭字段有: Server, Connection...。
響應(yīng)主體包含回車符、換行符和響應(yīng)返回?cái)?shù)據(jù),并不是所有響應(yīng)報(bào)文都有響應(yīng)數(shù)據(jù)
服務(wù)器返回給瀏覽器的文本信息,通常HTML, CSS, JS, 圖片等文件就放在這一部分。
瀏覽器解析渲染頁面
瀏覽器拿到index.html文件后,就開始解析其中的html代碼,遇到j(luò)s/css/image等靜態(tài)資源時(shí),就向服務(wù)器端去請(qǐng)求下載(會(huì)使用多線程下載,每個(gè)瀏覽器的線程數(shù)不一樣),這個(gè)時(shí)候就用上keep-alive特性了,建立一次HTTP連接,可以請(qǐng)求多個(gè)資源,下載資源的順序就是按照代碼里的順序,但是由于每個(gè)資源大小不一樣,而瀏覽器又多線程請(qǐng)求請(qǐng)求資源,所以顯示的順序并不一定是代碼里面的順序。
如遇到圖像,iconfont,JS等的請(qǐng)求時(shí),由于請(qǐng)求過程是異步的,并不會(huì)影響HTML文檔進(jìn)行加載,但是當(dāng)文檔加載過程中遇到JS文件,HTML文檔會(huì)掛起渲染過程,不僅要等到文檔中JS文件加載完畢還要等待解析執(zhí)行完畢,才會(huì)繼續(xù)HTML的渲染過程。原因是因?yàn)镴S有可能修改DOM結(jié)構(gòu),這就意味著JS執(zhí)行完成前,后續(xù)所有資源的下載是沒有必要的,這就是JS阻塞后續(xù)資源下載的根本原因。CSS文件的加載不影響JS文件的加載,但是卻影響JS文件的執(zhí)行。JS代碼執(zhí)行前瀏覽器必須保證CSS文件已經(jīng)下載并加載完畢。
瀏覽器在請(qǐng)求靜態(tài)資源時(shí)(在未過期的情況下),向服務(wù)器端發(fā)起一個(gè)http請(qǐng)求(詢問自從上一次修改時(shí)間到現(xiàn)在有沒有對(duì)資源進(jìn)行修改),如果服務(wù)器端返回304狀態(tài)碼(告訴瀏覽器服務(wù)器端沒有修改),那么瀏覽器會(huì)直接讀取本地的該資源的緩存文件。
接下來看一下瀏覽器渲染頁面的過程,如下圖:瀏覽器解析渲染頁面分為一下五個(gè)步驟:
根據(jù) HTML 解析出 DOM 樹
根據(jù) CSS 解析生成 CSS 規(guī)則樹
結(jié)合 DOM 樹和 CSS 規(guī)則樹,生成渲染樹
根據(jù)渲染樹計(jì)算每一個(gè)節(jié)點(diǎn)的信息
根據(jù)計(jì)算好的信息繪制頁面
瀏覽器是一個(gè)邊解析邊渲染的過程。首先瀏覽器解析HTML文件構(gòu)建DOM樹,然后解析CSS文件構(gòu)建渲染樹,等到渲染樹構(gòu)建完成后,瀏覽器開始布局渲染樹并將其繪制到屏幕上。這個(gè)過程比較復(fù)雜,涉及到兩個(gè)概念: reflow(回流)和repain(重繪)。DOM節(jié)點(diǎn)中的各個(gè)元素都是以盒模型的形式存在,這些都需要瀏覽器去計(jì)算其位置和大小等,這個(gè)過程稱為relow;當(dāng)盒模型的位置,大小以及其他屬性,如顏色,字體,等確定下來之后,瀏覽器便開始繪制內(nèi)容,這個(gè)過程稱為repain。頁面在首次加載時(shí)必然會(huì)經(jīng)歷reflow和repain。reflow和repain過程是非常消耗性能的,尤其是在移動(dòng)設(shè)備上,它會(huì)破壞用戶體驗(yàn),有時(shí)會(huì)造成頁面卡頓。所以我們應(yīng)該盡可能少的減少reflow和repain。
根據(jù) HTML 解析 DOM 樹
根據(jù) HTML 的內(nèi)容,將標(biāo)簽按照結(jié)構(gòu)解析成為 DOM 樹,DOM 樹解析的過程是一個(gè)深度優(yōu)先遍歷。即先構(gòu)建當(dāng)前節(jié)點(diǎn)的所有子節(jié)點(diǎn),再構(gòu)建下一個(gè)兄弟節(jié)點(diǎn)。
在讀取 HTML 文檔,構(gòu)建 DOM 樹的過程中,若遇到 script 標(biāo)簽,則 DOM 樹的構(gòu)建會(huì)暫停,直至腳本執(zhí)行完畢。
根據(jù) CSS 解析生成 CSS 規(guī)則樹
解析 CSS 規(guī)則樹時(shí) js 執(zhí)行將暫停,直至 CSS 規(guī)則樹就緒。
瀏覽器在 CSS 規(guī)則樹生成之前不會(huì)進(jìn)行渲染。
結(jié)合 DOM 樹和 CSS 規(guī)則樹,生成渲染樹
DOM 樹和 CSS 規(guī)則樹全部準(zhǔn)備好了以后,瀏覽器才會(huì)開始構(gòu)建渲染樹。
精簡(jiǎn) CSS 并可以加快 CSS 規(guī)則樹的構(gòu)建,從而加快頁面相應(yīng)速度。
根據(jù)渲染樹計(jì)算每一個(gè)節(jié)點(diǎn)的信息(布局)
布局:通過渲染樹中渲染對(duì)象的信息,計(jì)算出每一個(gè)渲染對(duì)象的位置和尺寸
回流:在布局完成后,發(fā)現(xiàn)了某個(gè)部分發(fā)生了變化影響了布局,那就需要倒回去重新渲染。
根據(jù)計(jì)算好的信息繪制頁面
繪制階段,系統(tǒng)會(huì)遍歷呈現(xiàn)樹,并調(diào)用呈現(xiàn)器的“paint”方法,將呈現(xiàn)器的內(nèi)容顯示在屏幕上。
重繪:某個(gè)元素的背景顏色,文字顏色等,不影響元素周圍或內(nèi)部布局的屬性,將只會(huì)引起瀏覽器的重繪。
回流:某個(gè)元素的尺寸發(fā)生了變化,則需重新計(jì)算渲染樹,重新渲染。
詳細(xì)的瀏覽器原理:請(qǐng)戳這里
斷開連接
當(dāng)數(shù)據(jù)傳送完畢,需要斷開 tcp 連接,此時(shí)發(fā)起 tcp 四次揮手。
發(fā)起方向被動(dòng)方發(fā)送報(bào)文,F(xiàn)in、Ack、Seq,表示已經(jīng)沒有數(shù)據(jù)傳輸了。并進(jìn)入 FIN_WAIT_1 狀態(tài)。(第一次揮手:由瀏覽器發(fā)起的,發(fā)送給服務(wù)器,我請(qǐng)求報(bào)文發(fā)送完了,你準(zhǔn)備關(guān)閉吧)
被動(dòng)方發(fā)送報(bào)文,Ack、Seq,表示同意關(guān)閉請(qǐng)求。此時(shí)主機(jī)發(fā)起方進(jìn)入 FIN_WAIT_2 狀態(tài)。(第二次揮手:由服務(wù)器發(fā)起的,告訴瀏覽器,我請(qǐng)求報(bào)文接受完了,我準(zhǔn)備關(guān)閉了,你也準(zhǔn)備吧)
被動(dòng)方向發(fā)起方發(fā)送報(bào)文段,F(xiàn)in、Ack、Seq,請(qǐng)求關(guān)閉連接。并進(jìn)入 LAST_ACK 狀態(tài)。(第三次揮手:由服務(wù)器發(fā)起,告訴瀏覽器,我響應(yīng)報(bào)文發(fā)送完了,你準(zhǔn)備關(guān)閉吧)
發(fā)起方向被動(dòng)方發(fā)送報(bào)文段,Ack、Seq。然后進(jìn)入等待 TIME_WAIT 狀態(tài)。被動(dòng)方收到發(fā)起方的報(bào)文段以后關(guān)閉連接。發(fā)起方等待一定時(shí)間未收到回復(fù),則正常關(guān)閉。(第四次揮手:由瀏覽器發(fā)起,告訴服務(wù)器,我響應(yīng)報(bào)文接受完了,我準(zhǔn)備關(guān)閉了,你也準(zhǔn)備吧)