DNS 查詢
時(shí)間:2023-02-02 09:04:01 | 來源:建站知識(shí)
時(shí)間:2023-02-02 09:04:01 來源:建站知識(shí)
- 瀏覽器檢查域名是否在緩存當(dāng)中(要查看 Chrome 當(dāng)中的緩存, 打開 chrome://net-internals/#dns)。
- 如果緩存中沒有,就去調(diào)用
gethostbyname
庫函數(shù)(操作系統(tǒng)不同函數(shù)也不同)進(jìn)行查詢。 gethostbyname
函數(shù)在試圖進(jìn)行DNS解析之前首先檢查域名是否在本地 Hosts 里,Hosts 的位置 不同的操作系統(tǒng)有所不同- 如果
gethostbyname
沒有這個(gè)域名的緩存記錄,也沒有在 hosts
里找到,它將會(huì)向 DNS 服務(wù)器發(fā)送一條 DNS 查詢請求。DNS 服務(wù)器是由網(wǎng)絡(luò)通信棧提供的,通常是本地路由器或者 ISP 的緩存 DNS 服務(wù)器。 - 查詢本地 DNS 服務(wù)器
- 如果 DNS 服務(wù)器和我們的主機(jī)在同一個(gè)子網(wǎng)內(nèi),系統(tǒng)會(huì)按照下面的 ARP 過程對 DNS 服務(wù)器進(jìn)行 ARP查詢
- 如果 DNS 服務(wù)器和我們的主機(jī)在不同的子網(wǎng),系統(tǒng)會(huì)按照下面的 ARP 過程對默認(rèn)網(wǎng)關(guān)進(jìn)行查詢
ARP 過程
要想發(fā)送 ARP(地址解析協(xié)議)廣播,我們需要有一個(gè)目標(biāo) IP 地址,同時(shí)還需要知道用于發(fā)送 ARP 廣播的接口的 MAC 地址。
- 首先查詢 ARP 緩存,如果緩存命中,我們返回結(jié)果:目標(biāo) IP = MAC
如果緩存沒有命中:
- 查看路由表,看看目標(biāo) IP 地址是不是在本地路由表中的某個(gè)子網(wǎng)內(nèi)。是的話,使用跟那個(gè)子網(wǎng)相連的接口,否則使用與默認(rèn)網(wǎng)關(guān)相連的接口。
- 查詢選擇的網(wǎng)絡(luò)接口的 MAC 地址
- 我們發(fā)送一個(gè)二層( OSI 模型 中的數(shù)據(jù)鏈路層)ARP 請求:
ARP Request
:
Sender MAC: interface:mac:address:hereSender IP: interface.ip.goes.hereTarget MAC: FF:FF:FF:FF:FF:FF (Broadcast)Target IP: target.ip.goes.here
根據(jù)連接主機(jī)和路由器的硬件類型不同,可以分為以下幾種情況:
直連:
- 如果我們和路由器是直接連接的,路由器會(huì)返回一個(gè)
ARP Reply
(見下面)。
集線器:
- 如果我們連接到一個(gè)集線器,集線器會(huì)把 ARP 請求向所有其它端口廣播,如果路由器也“連接”在其中,它會(huì)返回一個(gè)
ARP Reply
。
交換機(jī):
- 如果我們連接到了一個(gè)交換機(jī),交換機(jī)會(huì)檢查本地 CAM/MAC 表,看看哪個(gè)端口有我們要找的那個(gè) MAC 地址,如果沒有找到,交換機(jī)會(huì)向所有其它端口廣播這個(gè) ARP 請求。
- 如果交換機(jī)的 MAC/CAM 表中有對應(yīng)的條目,交換機(jī)會(huì)向有我們想要查詢的 MAC 地址的那個(gè)端口發(fā)送 ARP 請求
- 如果路由器也“連接”在其中,它會(huì)返回一個(gè)
ARP Reply
ARP Reply
:
Sender MAC: target:mac:address:hereSender IP: target.ip.goes.hereTarget MAC: interface:mac:address:hereTarget IP: interface.ip.goes.here
現(xiàn)在我們有了 DNS 服務(wù)器或者默認(rèn)網(wǎng)關(guān)的 IP 地址,我們可以繼續(xù) DNS 請求了:
- 使用 53 端口向 DNS 服務(wù)器發(fā)送 UDP 請求包,如果響應(yīng)包太大,會(huì)使用 TCP 協(xié)議
- 如果本地/ISP DNS 服務(wù)器沒有找到結(jié)果,它會(huì)發(fā)送一個(gè)遞歸查詢請求,一層一層向高層 DNS 服務(wù)器做查詢,直到查詢到起始授權(quán)機(jī)構(gòu),如果找到會(huì)把結(jié)果返回
使用套接字
當(dāng)瀏覽器得到了目標(biāo)服務(wù)器的 IP 地址,以及 URL 中給出來端口號(http 協(xié)議默認(rèn)端口號是 80, https 默認(rèn)端口號是 443),它會(huì)調(diào)用系統(tǒng)庫函數(shù)
socket
,請求一個(gè) TCP流套接字,對應(yīng)的參數(shù)是
AF_INET/AF_INET6
和
SOCK_STREAM
。
- 這個(gè)請求首先被交給傳輸層,在傳輸層請求被封裝成 TCP segment。目標(biāo)端口會(huì)被加入頭部,源端口會(huì)在系統(tǒng)內(nèi)核的動(dòng)態(tài)端口范圍內(nèi)選?。↙inux下是ip_local_port_range)
- TCP segment 被送往網(wǎng)絡(luò)層,網(wǎng)絡(luò)層會(huì)在其中再加入一個(gè) IP 頭部,里面包含了目標(biāo)服務(wù)器的IP地址以及本機(jī)的IP地址,把它封裝成一個(gè)IP packet。
- 這個(gè) TCP packet 接下來會(huì)進(jìn)入鏈路層,鏈路層會(huì)在封包中加入 frame 頭部,里面包含了本地內(nèi)置網(wǎng)卡的MAC地址以及網(wǎng)關(guān)(本地路由器)的 MAC 地址。像前面說的一樣,如果內(nèi)核不知道網(wǎng)關(guān)的 MAC 地址,它必須進(jìn)行 ARP 廣播來查詢其地址。
到了現(xiàn)在,TCP 封包已經(jīng)準(zhǔn)備好了,可以使用下面的方式進(jìn)行傳輸:
- 以太網(wǎng)
- WiFi
- 蜂窩數(shù)據(jù)網(wǎng)絡(luò)
對于大部分家庭網(wǎng)絡(luò)和小型企業(yè)網(wǎng)絡(luò)來說,封包會(huì)從本地計(jì)算機(jī)出發(fā),經(jīng)過本地網(wǎng)絡(luò),再通過調(diào)制解調(diào)器把數(shù)字信號轉(zhuǎn)換成模擬信號,使其適于在電話線路,有線電視光纜和無線電話線路上傳輸。在傳輸線路的另一端,是另外一個(gè)調(diào)制解調(diào)器,它把模擬信號轉(zhuǎn)換回?cái)?shù)字信號,交由下一個(gè) 網(wǎng)絡(luò)節(jié)點(diǎn) 處理。節(jié)點(diǎn)的目標(biāo)地址和源地址將在后面討論。
大型企業(yè)和比較新的住宅通常使用光纖或直接以太網(wǎng)連接,這種情況下信號一直是數(shù)字的,會(huì)被直接傳到下一個(gè) 網(wǎng)絡(luò)節(jié)點(diǎn) 進(jìn)行處理。
最終封包會(huì)到達(dá)管理本地子網(wǎng)的路由器。在那里出發(fā),它會(huì)繼續(xù)經(jīng)過自治區(qū)域(autonomous system, 縮寫 AS)的邊界路由器,其他自治區(qū)域,最終到達(dá)目標(biāo)服務(wù)器。一路上經(jīng)過的這些路由器會(huì)從IP數(shù)據(jù)報(bào)頭部里提取出目標(biāo)地址,并將封包正確地路由到下一個(gè)目的地。IP數(shù)據(jù)報(bào)頭部 time to live (TTL) 域的值每經(jīng)過一個(gè)路由器就減1,如果封包的TTL變?yōu)?,或者路由器由于網(wǎng)絡(luò)擁堵等原因封包隊(duì)列滿了,那么這個(gè)包會(huì)被路由器丟棄。
上面的發(fā)送和接受過程在 TCP 連接期間會(huì)發(fā)生很多次:
- 客戶端選擇一個(gè)初始序列號(ISN),將設(shè)置了 SYN 位的封包發(fā)送給服務(wù)器端,表明自己要建立連接并設(shè)置了初始序列號
- 服務(wù)器端接收到 SYN 包,如果它可以建立連接:
- 服務(wù)器端選擇它自己的初始序列號
- 服務(wù)器端設(shè)置 SYN 位,表明自己選擇了一個(gè)初始序列號
- 服務(wù)器端把 (客戶端ISN + 1) 復(fù)制到 ACK 域,并且設(shè)置 ACK 位,表明自己接收到了客戶端的第一個(gè)封包
- 客戶端通過發(fā)送下面一個(gè)封包來確認(rèn)這次連接:
- 自己的序列號+1
- 接收端 ACK+1
- 設(shè)置 ACK 位
- 數(shù)據(jù)通過下面的方式傳輸:
- 當(dāng)一方發(fā)送了N個(gè) Bytes 的數(shù)據(jù)之后,將自己的 SEQ 序列號也增加N
- 另一方確認(rèn)接收到這個(gè)數(shù)據(jù)包(或者一系列數(shù)據(jù)包)之后,它發(fā)送一個(gè) ACK 包,ACK 的值設(shè)置為接收到的數(shù)據(jù)包的最后一個(gè)序列號
- 關(guān)閉連接時(shí):
- 要關(guān)閉連接的一方發(fā)送一個(gè) FIN 包
- 另一方確認(rèn)這個(gè) FIN 包,并且發(fā)送自己的 FIN 包
- 要關(guān)閉的一方使用 ACK 包來確認(rèn)接收到了 FIN
TLS 握手
- 客戶端發(fā)送一個(gè)
ClientHello
消息到服務(wù)器端,消息中同時(shí)包含了它的 Transport Layer Security (TLS) 版本,可用的加密算法和壓縮算法。 - 服務(wù)器端向客戶端返回一個(gè)
ServerHello
消息,消息中包含了服務(wù)器端的TLS版本,服務(wù)器所選擇的加密和壓縮算法,以及數(shù)字證書認(rèn)證機(jī)構(gòu)(Certificate Authority,縮寫 CA)簽發(fā)的服務(wù)器公開證書,證書中包含了公鑰。客戶端會(huì)使用這個(gè)公鑰加密接下來的握手過程,直到協(xié)商生成一個(gè)新的對稱密鑰 - 客戶端根據(jù)自己的信任CA列表,驗(yàn)證服務(wù)器端的證書是否可信。如果認(rèn)為可信,客戶端會(huì)生成一串偽隨機(jī)數(shù),使用服務(wù)器的公鑰加密它。這串隨機(jī)數(shù)會(huì)被用于生成新的對稱密鑰
- 服務(wù)器端使用自己的私鑰解密上面提到的隨機(jī)數(shù),然后使用這串隨機(jī)數(shù)生成自己的對稱主密鑰
- 客戶端發(fā)送一個(gè)
Finished
消息給服務(wù)器端,使用對稱密鑰加密這次通訊的一個(gè)散列值 - 服務(wù)器端生成自己的 hash 值,然后解密客戶端發(fā)送來的信息,檢查這兩個(gè)值是否對應(yīng)。如果對應(yīng),就向客戶端發(fā)送一個(gè)
Finished
消息,也使用協(xié)商好的對稱密鑰加密 - 從現(xiàn)在開始,接下來整個(gè) TLS 會(huì)話都使用對稱秘鑰進(jìn)行加密,傳輸應(yīng)用層(HTTP)內(nèi)容
HTTP 協(xié)議
如果瀏覽器是 Google 出品的,它不會(huì)使用 HTTP 協(xié)議來獲取頁面信息,而是會(huì)與服務(wù)器端發(fā)送請求,商討使用 SPDY 協(xié)議。
如果瀏覽器使用 HTTP 協(xié)議而不支持 SPDY 協(xié)議,它會(huì)向服務(wù)器發(fā)送這樣的一個(gè)請求:
GET / HTTP/1.1Host: google.comConnection: close[其他頭部]
“其他頭部”包含了一系列的由冒號分割開的鍵值對,它們的格式符合HTTP協(xié)議標(biāo)準(zhǔn),它們之間由一個(gè)換行符分割開來。(這里我們假設(shè)瀏覽器沒有違反HTTP協(xié)議標(biāo)準(zhǔn)的bug,同時(shí)假設(shè)瀏覽器使用
HTTP/1.1
協(xié)議,不然的話頭部可能不包含
Host
字段,同時(shí)
GET
請求中的版本號會(huì)變成
HTTP/1.0
或者
HTTP/0.9
。)
HTTP/1.1 定義了“關(guān)閉連接”的選項(xiàng) "close",發(fā)送者使用這個(gè)選項(xiàng)指示這次連接在響應(yīng)結(jié)束之后會(huì)斷開。例如:
Connection:close
不支持持久連接的 HTTP/1.1 應(yīng)用必須在每條消息中都包含 "close" 選項(xiàng)。
在發(fā)送完這些請求和頭部之后,瀏覽器發(fā)送一個(gè)換行符,表示要發(fā)送的內(nèi)容已經(jīng)結(jié)束了。
服務(wù)器端返回一個(gè)響應(yīng)碼,指示這次請求的狀態(tài),響應(yīng)的形式是這樣的:
200 OK[響應(yīng)頭部]
然后是一個(gè)換行,接下來有效載荷(payload),也就是
www.google.com
的HTML內(nèi)容。服務(wù)器下面可能會(huì)關(guān)閉連接,如果客戶端請求保持連接的話,服務(wù)器端會(huì)保持連接打開,以供之后的請求重用。
如果瀏覽器發(fā)送的HTTP頭部包含了足夠多的信息(例如包含了 Etag 頭部),以至于服務(wù)器可以判斷出,瀏覽器緩存的文件版本自從上次獲取之后沒有再更改過,服務(wù)器可能會(huì)返回這樣的響應(yīng):
304 Not Modified[響應(yīng)頭部]
這個(gè)響應(yīng)沒有有效載荷,瀏覽器會(huì)從自己的緩存中取出想要的內(nèi)容。
在解析完 HTML 之后,瀏覽器和客戶端會(huì)重復(fù)上面的過程,直到HTML頁面引入的所有資源(圖片,CSS,favicon.ico等等)全部都獲取完畢,區(qū)別只是頭部的
GET / HTTP/1.1
會(huì)變成
GET /$(相對www.google.com的URL) HTTP/1.1
。
如果HTML引入了
www.google.com
域名之外的資源,瀏覽器會(huì)回到上面解析域名那一步,按照下面的步驟往下一步一步執(zhí)行,請求中的
Host
頭部會(huì)變成另外的域名。
HTTP 服務(wù)器請求處理
HTTPD(HTTP Daemon)在服務(wù)器端處理請求/響應(yīng)。最常見的 HTTPD 有 Linux 上常用的 Apache 和 nginx,以及 Windows 上的 IIS。
- HTTPD 接收請求
- 服務(wù)器把請求拆分為以下幾個(gè)參數(shù):
- HTTP 請求方法(
GET
, POST
, HEAD
, PUT
, DELETE
, CONNECT
, OPTIONS
, 或者 TRACE
)。直接在地址欄中輸入 URL 這種情況下,使用的是 GET 方法 - 域名:http://google.com
- 請求路徑/頁面:/ (我們沒有請求http://google.com下的指定的頁面,因此 / 是默認(rèn)的路徑)
- 服務(wù)器驗(yàn)證其上已經(jīng)配置了 http://google.com 的虛擬主機(jī)
- 服務(wù)器驗(yàn)證 http://google.com 接受 GET 方法
- 服務(wù)器驗(yàn)證該用戶可以使用 GET 方法(根據(jù) IP 地址,身份信息等)
- 如果服務(wù)器安裝了 URL 重寫模塊(例如 Apache 的 mod_rewrite 和 IIS 的 URL Rewrite),服務(wù)器會(huì)嘗試匹配重寫規(guī)則,如果匹配上的話,服務(wù)器會(huì)按照規(guī)則重寫這個(gè)請求
- 服務(wù)器根據(jù)請求信息獲取相應(yīng)的響應(yīng)內(nèi)容,這種情況下由于訪問路徑是 "/" ,會(huì)訪問首頁文件(你可以重寫這個(gè)規(guī)則,但是這個(gè)是最常用的)。
- 服務(wù)器會(huì)使用指定的處理程序分析處理這個(gè)文件,假如 Google 使用 PHP,服務(wù)器會(huì)使用 PHP 解析 index 文件,并捕獲輸出,把 PHP 的輸出結(jié)果返回給請求者
瀏覽器背后的故事
當(dāng)服務(wù)器提供了資源之后(HTML,CSS,JS,圖片等),瀏覽器會(huì)執(zhí)行下面的操作:
- 解析 —— HTML,CSS,JS
- 渲染 —— 構(gòu)建 DOM 樹 -> 渲染 -> 布局 -> 繪制
瀏覽器
瀏覽器的功能是從服務(wù)器上取回你想要的資源,然后展示在瀏覽器窗口當(dāng)中。資源通常是 HTML 文件,也可能是 PDF,圖片,或者其他類型的內(nèi)容。資源的位置通過用戶提供的 URI(Uniform Resource Identifier) 來確定。
瀏覽器解釋和展示 HTML 文件的方法,在 HTML 和 CSS 的標(biāo)準(zhǔn)中有詳細(xì)介紹。這些標(biāo)準(zhǔn)由 Web 標(biāo)準(zhǔn)組織 W3C(World Wide Web Consortium) 維護(hù)。
不同瀏覽器的用戶界面大都十分接近,有很多共同的 UI 元素:
- 一個(gè)地址欄
- 后退和前進(jìn)按鈕
- 書簽選項(xiàng)
- 刷新和停止按鈕
- 主頁按鈕
瀏覽器高層架構(gòu)組成瀏覽器的組件有:
- 用戶界面 用戶界面包含了地址欄,前進(jìn)后退按鈕,書簽菜單等等,除了請求頁面之外所有你看到的內(nèi)容都是用戶界面的一部分
- 瀏覽器引擎 瀏覽器引擎負(fù)責(zé)讓 UI 和渲染引擎協(xié)調(diào)工作
- 渲染引擎 渲染引擎負(fù)責(zé)展示請求內(nèi)容。如果請求的內(nèi)容是 HTML,渲染引擎會(huì)解析 HTML 和 CSS,然后將內(nèi)容展示在屏幕上
- 網(wǎng)絡(luò)組件 網(wǎng)絡(luò)組件負(fù)責(zé)網(wǎng)絡(luò)調(diào)用,例如 HTTP 請求等,使用一個(gè)平臺(tái)無關(guān)接口,下層是針對不同平臺(tái)的具體實(shí)現(xiàn)
- UI后端 UI 后端用于繪制基本 UI 組件,例如下拉列表框和窗口。UI 后端暴露一個(gè)統(tǒng)一的平臺(tái)無關(guān)的接口,下層使用操作系統(tǒng)的 UI 方法實(shí)現(xiàn)
- Javascript 引擎 Javascript 引擎用于解析和執(zhí)行 Javascript 代碼
- 數(shù)據(jù)存儲(chǔ) 數(shù)據(jù)存儲(chǔ)組件是一個(gè)持久層。瀏覽器可能需要在本地存儲(chǔ)各種各樣的數(shù)據(jù),例如 Cookie 等。瀏覽器也需要支持諸如 localStorage,IndexedDB,WebSQL 和 FileSystem 之類的存儲(chǔ)機(jī)制
HTML 解析
瀏覽器渲染引擎從網(wǎng)絡(luò)層取得請求的文檔,一般情況下文檔會(huì)分成8kB大小的分塊傳輸。
HTML 解析器的主要工作是對 HTML 文檔進(jìn)行解析,生成解析樹。
解析樹是以 DOM 元素以及屬性為節(jié)點(diǎn)的樹。DOM是文檔對象模型(Document Object Model)的縮寫,它是 HTML 文檔的對象表示,同時(shí)也是 HTML 元素面向外部(如Javascript)的接口。樹的根部是"Document"對象。整個(gè) DOM 和 HTML 文檔幾乎是一對一的關(guān)系。
解析算法HTML不能使用常見的自頂向下或自底向上方法來進(jìn)行分析。主要原因有以下幾點(diǎn):
- 語言本身的“寬容”特性
- HTML 本身可能是殘缺的,對于常見的殘缺,瀏覽器需要有傳統(tǒng)的容錯(cuò)機(jī)制來支持它們
- 解析過程需要反復(fù)。對于其他語言來說,源碼不會(huì)在解析過程中發(fā)生變化,但是對于 HTML 來說,動(dòng)態(tài)代碼,例如腳本元素中包含的 document.write() 方法會(huì)在源碼中添加內(nèi)容,也就是說,解析過程實(shí)際上會(huì)改變輸入的內(nèi)容
由于不能使用常用的解析技術(shù),瀏覽器創(chuàng)造了專門用于解析 HTML 的解析器。解析算法在 HTML5 標(biāo)準(zhǔn)規(guī)范中有詳細(xì)介紹,算法主要包含了兩個(gè)階段:標(biāo)記化(tokenization)和樹的構(gòu)建。
解析結(jié)束之后瀏覽器開始加載網(wǎng)頁的外部資源(CSS,圖像,Javascript 文件等)。
此時(shí)瀏覽器把文檔標(biāo)記為可交互的(interactive),瀏覽器開始解析處于“推遲(deferred)”模式的腳本,也就是那些需要在文檔解析完畢之后再執(zhí)行的腳本。之后文檔的狀態(tài)會(huì)變?yōu)椤巴瓿桑╟omplete)”,瀏覽器會(huì)觸發(fā)“加載(load)”事件。
注意解析 HTML 網(wǎng)頁時(shí)永遠(yuǎn)不會(huì)出現(xiàn)“無效語法(Invalid Syntax)”錯(cuò)誤,瀏覽器會(huì)修復(fù)所有錯(cuò)誤內(nèi)容,然后繼續(xù)解析。
CSS 解析
- 根據(jù) CSS詞法和句法 分析CSS文件和
<style>
標(biāo)簽包含的內(nèi)容以及 style 屬性的值 - 每個(gè)CSS文件都被解析成一個(gè)樣式表對象(
StyleSheet object
),這個(gè)對象里包含了帶有選擇器的CSS規(guī)則,和對應(yīng)CSS語法的對象 - CSS解析器可能是自頂向下的,也可能是使用解析器生成器生成的自底向上的解析器
頁面渲染
- 通過遍歷DOM節(jié)點(diǎn)樹創(chuàng)建一個(gè)“Frame 樹”或“渲染樹”,并計(jì)算每個(gè)節(jié)點(diǎn)的各個(gè)CSS樣式值
- 通過累加子節(jié)點(diǎn)的寬度,該節(jié)點(diǎn)的水平內(nèi)邊距(padding)、邊框(border)和外邊距(margin),自底向上的計(jì)算"Frame 樹"中每個(gè)節(jié)點(diǎn)的首選(preferred)寬度
- 通過自頂向下的給每個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)分配可行寬度,計(jì)算每個(gè)節(jié)點(diǎn)的實(shí)際寬度
- 通過應(yīng)用文字折行、累加子節(jié)點(diǎn)的高度和此節(jié)點(diǎn)的內(nèi)邊距(padding)、邊框(border)和外邊距(margin),自底向上的計(jì)算每個(gè)節(jié)點(diǎn)的高度
- 使用上面的計(jì)算結(jié)果構(gòu)建每個(gè)節(jié)點(diǎn)的坐標(biāo)
- 當(dāng)存在元素使用
floated
,位置有 absolutely
或 relatively
屬性的時(shí)候,會(huì)有更多復(fù)雜的計(jì)算,詳見http://dev.w3.org/csswg/css2/ 和 http://www.w3.org/Style/CSS/current-work - 創(chuàng)建layer(層)來表示頁面中的哪些部分可以成組的被繪制,而不用被重新柵格化處理。每個(gè)幀對象都被分配給一個(gè)層
- 頁面上的每個(gè)層都被分配了紋理(?)
- 每個(gè)層的幀對象都會(huì)被遍歷,計(jì)算機(jī)執(zhí)行繪圖命令繪制各個(gè)層,此過程可能由CPU執(zhí)行柵格化處理,或者直接通過D2D/SkiaGL在GPU上繪制
- 上面所有步驟都可能利用到最近一次頁面渲染時(shí)計(jì)算出來的各個(gè)值,這樣可以減少不少計(jì)算量
- 計(jì)算出各個(gè)層的最終位置,一組命令由 Direct3D/OpenGL發(fā)出,GPU命令緩沖區(qū)清空,命令傳至GPU并異步渲染,幀被送到Window Server。
GPU 渲染
- 在渲染過程中,圖形處理層可能使用通用用途的
CPU
,也可能使用圖形處理器 GPU
- 當(dāng)使用
GPU
用于圖形渲染時(shí),圖形驅(qū)動(dòng)軟件會(huì)把任務(wù)分成多個(gè)部分,這樣可以充分利用 GPU
強(qiáng)大的并行計(jì)算能力,用于在渲染過程中進(jìn)行大量的浮點(diǎn)計(jì)算。
Window Server
后期渲染與用戶引發(fā)的處理
渲染結(jié)束后,瀏覽器根據(jù)某些時(shí)間機(jī)制運(yùn)行JavaScript代碼(比如Google Doodle動(dòng)畫)或與用戶交互(在搜索欄輸入關(guān)鍵字獲得搜索建議)。類似Flash和Java的插件也會(huì)運(yùn)行,盡管Google主頁里沒有。這些腳本可以觸發(fā)網(wǎng)絡(luò)請求,也可能改變網(wǎng)頁的內(nèi)容和布局,產(chǎn)生又一輪渲染與繪制。
https://github.com/skyline75489/what-happens-when-zh_CN