對(duì)于面試的大部分前端開(kāi)發(fā)者來(lái)說(shuō),對(duì)瀏覽器的了解也算是一知半解,因?yàn)槲覀円婚_(kāi)始前端覺(jué)得,我們開(kāi)發(fā)中通常使用瀏覽器來(lái)顯示和調(diào)試頁(yè)面用的,不會(huì)涉入到太過(guò)的相關(guān)瀏覽器工作原理知識(shí)。
這你就大錯(cuò)特錯(cuò)了,雖然瀏覽器默默的為我們工作,但是有關(guān)瀏覽器的工作原理不但在你就業(yè)前端面試中屬于重中之重,也是在前端優(yōu)化中占有很大比重。作為一個(gè)前端開(kāi)發(fā)如果不了解瀏覽器的工作原理,只能永遠(yuǎn)停留在前端“切圖仔”水平。
PS:前幾天還有個(gè)讀者和小鹿說(shuō),之前看到小鹿朋友圈發(fā)過(guò)這個(gè)這個(gè)導(dǎo)圖,當(dāng)時(shí)沒(méi)當(dāng)回事,第二天面試竟然問(wèn)到了。
學(xué)習(xí)瀏覽器工作原理是為了能夠運(yùn)用到實(shí)際項(xiàng)目中,比如前端的性能優(yōu)化以及錯(cuò)誤排查,都會(huì)涉及到瀏覽器相關(guān)的知識(shí),所以掌握瀏覽器的工作原理是必不可缺的,相信你學(xué)完之后,能夠?qū)δ愕膫€(gè)人能力和見(jiàn)識(shí)會(huì)有很大的提升。
瀏覽器涉及到的知識(shí)點(diǎn)非常多而且非常重要,文章中可能其中有不足和錯(cuò)誤的地方,也歡迎各位指出!
思維導(dǎo)圖
1、瀏覽器的職責(zé)
我們由淺入深的去了解瀏覽器的工作原理。首先學(xué)習(xí)一個(gè)事物要知道它是什么,它要完成一個(gè)什么樣的事情,也就是擁有什么樣的職責(zé)。
對(duì)于瀏覽器來(lái)說(shuō),表面上看來(lái),我們輸入了 URL,然后等待幾秒瀏覽器就展現(xiàn)出我們想要訪問(wèn)的網(wǎng)址內(nèi)容了。對(duì)沒(méi)錯(cuò),這就是瀏覽器的職責(zé)所在。這只是停留在了表面,要想深入知道瀏覽器在這個(gè)階段發(fā)生了什么?需要我們進(jìn)一步探索瀏覽器的工作原理。
所以說(shuō),無(wú)論是面試還是實(shí)際工作中,瀏覽器無(wú)時(shí)不刻和我們打交道。那我們就要從在瀏覽器輸入 URL 開(kāi)始說(shuō)起,直到瀏覽器最后展現(xiàn)出網(wǎng)站內(nèi)容,這個(gè)過(guò)程瀏覽器做了哪些工作,又是如何工作的呢?
我們會(huì)詳細(xì)分為以下幾大模塊進(jìn)行系統(tǒng)的講解:
1、DNS 解析
2、TCP 連接
3、HTTP 請(qǐng)求
4、構(gòu)建 DOM 樹(shù)
5、構(gòu)建 CSSOM 樹(shù)
6、生成渲染樹(shù)
7、合成、繪制
其中有些部分我們之前的文章已經(jīng)分享過(guò),所以也不過(guò)到陳述,到時(shí)候會(huì)鞏固一下,重點(diǎn)我們放在瀏覽器的渲染原理上,這也是我們以后在學(xué)習(xí)前端優(yōu)化中的重點(diǎn)。
2、DNS 解析
在之前的文章 TCP 三次握手中提到,要想得到接收方的 MAC 地址,需要通過(guò)對(duì)方的 IP 地址獲取,對(duì)方的 IP 需要通過(guò) DNS 解析。
2.1 為什么進(jìn)行 DNS 解析?
所謂的 DNS 解析就是將我們輸入在網(wǎng)頁(yè)地址欄的 URL 通過(guò) DNS 解析成 IP 地址。DNS 就是將域名轉(zhuǎn)化成 ip 地址的過(guò)程。那么這個(gè)過(guò)程會(huì)發(fā)生什么呢?和小鹿一起深入探究一下。
2.2 系統(tǒng)緩存查詢
首先瀏覽器會(huì)調(diào)用一個(gè)庫(kù)函數(shù),檢測(cè)本地的 hosts 文件(可以認(rèn)為是電腦本地的一個(gè)地址映射文件),從該文件中查看是否有對(duì)應(yīng)的該域名的 IP 地址,這個(gè)過(guò)程是在系統(tǒng)緩存中查找是否存在該域名對(duì)應(yīng)的 IP 地址。
比如在瀏覽器的地址欄中輸入小鹿的博客網(wǎng)址(www.xiaolu.com),然后回車(chē),此時(shí)瀏覽器拿著這個(gè)域名去本地電腦的一個(gè)名為 hosts 文件中查詢是否存在該域名所對(duì)應(yīng)的 IP 地址,如果有,就返回給瀏覽器,如果沒(méi)有,我們繼續(xù)往下進(jìn)行。
2.3 路由器緩存、ISP 緩存
如果系統(tǒng)緩存沒(méi)有,就會(huì)向 DNS 服務(wù)器發(fā)送請(qǐng)求,而網(wǎng)絡(luò)服務(wù)一般都會(huì)先經(jīng)過(guò)路由器以及網(wǎng)絡(luò)服務(wù)商(電信),所以會(huì)先查詢路由器緩存,然后再查詢 ISP 的 DNS 緩存。
PS:ISP緩存,本身是一種寬帶接入提供商給網(wǎng)頁(yè)批量訪問(wèn)加速的技術(shù)。ISP會(huì)將當(dāng)前訪問(wèn)量較大的網(wǎng)頁(yè)內(nèi)容放到ISP服務(wù)器的緩存中,當(dāng)有新的用戶請(qǐng)求相同內(nèi)容時(shí),可以直接從緩存中發(fā)送相關(guān)信息,不必每次都去訪問(wèn)真正的網(wǎng)站,從而加快了不同用戶對(duì)相同內(nèi)容的訪問(wèn)速度,同時(shí)也能節(jié)省網(wǎng)間流量結(jié)算成本。
2.4 DNS 遞歸查詢
如果路由器緩存和 ISP 的 DNS 緩存還是沒(méi)有的話,我們就進(jìn)行 DNS 遞歸查詢。從根域名服務(wù)器開(kāi)始查詢,然后再到頂級(jí)域名服務(wù)器,最后到主域名服務(wù)器依次查詢。
但是這里有兩種查詢方式,不僅僅有遞歸查詢一種方式,還有一個(gè)查詢方式是迭代查詢,兩種查詢方式的區(qū)別是什么呢?
迭代查詢:DNS 收到請(qǐng)求時(shí),而不是直接返回查詢結(jié)果,而是告訴客戶端另一臺(tái) DNS 服務(wù)器地址。然后客戶端再向這臺(tái)的 DNS 服務(wù)器提交請(qǐng)求,依次循環(huán)。
遞歸查詢:當(dāng) DNS 服務(wù)器收到請(qǐng)求時(shí),就會(huì)檢查 DNS 緩存,如果沒(méi)有就會(huì)詢問(wèn)其他服務(wù)器,并將返回的查詢結(jié)果返回客戶端。
我們前端會(huì)在性能優(yōu)化的使用用到 DNS 的相關(guān)知識(shí),我們?cè)谶@稍微提一下,如何進(jìn)行 DNS 優(yōu)化呢?
DNS 查詢經(jīng)歷很多步驟,查詢很慢。瀏覽器獲取到 IP 地址后,一般都會(huì)加到瀏覽器的緩存中,本地的 DNS 緩存服務(wù)器,也可以去記錄。
另外使用 DNS 負(fù)載均衡,通常我們的網(wǎng)站應(yīng)用各種云服務(wù),DNS 系統(tǒng)根據(jù)每臺(tái)機(jī)器的負(fù)載量,地理位置的限制等等,去提供高效快速的 DNS 解析服務(wù)。
3、TCP 連接
我們通過(guò) DNS 查詢到 IP 地址之后,我們就開(kāi)始打算與服務(wù)器建立連接,為接下來(lái)的數(shù)據(jù)傳輸做準(zhǔn)備,這部分在之前的文章中寫(xiě)的非常詳細(xì),一定要去看哦。
網(wǎng)絡(luò)分層模型
動(dòng)畫(huà):用動(dòng)畫(huà)給面試官解釋 TCP 三次握手過(guò)程
4、HTTP 請(qǐng)求
我們客戶端與服務(wù)端通過(guò) TCP 的三次握手建立連接之后,客戶端開(kāi)始向服務(wù)器主動(dòng)發(fā)起請(qǐng)求。
PS:對(duì)于 HTTP 協(xié)議,我們會(huì)在后邊單獨(dú)拿出一篇文章來(lái)詳細(xì)介紹它的發(fā)展史,這里我們只涉及到 HTTP 的請(qǐng)求相關(guān)的內(nèi)容。
服務(wù)端接收到客戶端發(fā)送的信息,就返回響應(yīng)信息和文件??蛻舳巳绾闻袛喾?wù)端是否成功返回了呢?就需要下列的一些狀態(tài)碼來(lái)識(shí)別,同樣前端做的工作也是通過(guò)狀態(tài)碼來(lái)判斷當(dāng)前響應(yīng)狀態(tài)。
1XX(信息性狀態(tài)碼) : 服務(wù)器正在處理請(qǐng)求中。
2XX (成功狀態(tài)碼): 請(qǐng)求處理完畢。
3XX (重定向狀態(tài)碼): 需要附加操作以完成請(qǐng)求。301:永久性重定向。該狀態(tài)碼表示請(qǐng)求的資源已被分配了新的 URI,以后使用該資源,使用現(xiàn)在所指 URI。302:臨時(shí)性重定向。表示該狀態(tài)碼被分配了新的 URI,希望用戶本次能夠使用新的 URI 訪問(wèn)。304:服務(wù)器資源未改變,可直接使用客戶端未過(guò)期的緩存。
4XX (客戶端錯(cuò)誤狀態(tài)碼): 服務(wù)器無(wú)法處理請(qǐng)求。400:該請(qǐng)求報(bào)文中有語(yǔ)法錯(cuò)誤。403:沒(méi)有資源的訪問(wèn)權(quán)限。404:找不到資源。
5XX (服務(wù)端錯(cuò)誤狀態(tài)碼): 服務(wù)器處理請(qǐng)求出錯(cuò)。500:服務(wù)器發(fā)生錯(cuò)誤503:服務(wù)器超荷載或正在維護(hù)。
遠(yuǎn)程服務(wù)器找到資源并使用 HTTP 響應(yīng)返回該資源,值為 200 的 HTTP 響應(yīng)狀態(tài)表示一個(gè)正確的響應(yīng)。
5、瀏覽器的渲染原理
5.1 構(gòu)建 DOM
服務(wù)器將 HTML、CSS、JS文件轉(zhuǎn)化為 0,1字節(jié)數(shù)據(jù)在網(wǎng)絡(luò)中傳輸給瀏覽器,瀏覽器通過(guò)判斷狀態(tài)碼開(kāi)始接收、解析文件,這開(kāi)始運(yùn)用到瀏覽器的渲染原理。
首先瀏覽器要做的就是獲取 HTTP 的 Request 的 body 中字符串(字符流)的 HTML 文本,進(jìn)行解析并構(gòu)建 DOM 樹(shù)。
將字符流轉(zhuǎn)化為字符串之后,瀏覽器開(kāi)始進(jìn)行詞法分析,雖然這個(gè)名詞我們不熟悉,但是我們要知道,一個(gè) HTML 字符串我們要拆分開(kāi)才能構(gòu)建 DOM 樹(shù),詞法分析就是將字符串拆分成的過(guò)程。將字符串轉(zhuǎn)化為的 token(標(biāo)記) —— token 作為代碼的最小單位,也就是拆分后的結(jié)果,這個(gè)過(guò)程我們稱(chēng)為標(biāo)記化。
我們將字符串拆解之后,然后將這些標(biāo)記轉(zhuǎn)化為 Node 結(jié)點(diǎn),瀏覽器根據(jù)不同的結(jié)點(diǎn)開(kāi)始構(gòu)建一棵 DOM 樹(shù)。這就是整個(gè) DOM 樹(shù)構(gòu)建的過(guò)程,其中還涉及到很多的細(xì)節(jié),比如詞法分析是如何一個(gè)過(guò)程(狀態(tài)機(jī)),有興趣的小伙伴可以詳細(xì)查看英文文檔,在文章底部。
5.2 構(gòu)建 CSSOM 樹(shù)
瀏覽器已經(jīng)把 HTML 文件轉(zhuǎn)化為了 DOM 樹(shù),下面就對(duì) CSS 樣式文件進(jìn)行解析,構(gòu)建成 CSSOM 樹(shù)。這個(gè)過(guò)程和上述構(gòu)建 DOM 樹(shù)的過(guò)程有點(diǎn)相似,但是其中 CSSOM 樹(shù)的構(gòu)建更加的耗時(shí)。下面我們來(lái)看看如何耗時(shí)的?
瀏覽器通過(guò)遞歸的方式 DOM 樹(shù)為結(jié)點(diǎn)設(shè)置樣式。通過(guò)先找到具體的標(biāo)簽,然后遞歸找到設(shè)置的上級(jí)標(biāo)簽,最后確定選擇器選擇的所選標(biāo)簽的樣式。
比如下邊的例子,瀏覽器是如何確定結(jié)點(diǎn)的樣式的呢?
1
小鹿動(dòng)畫(huà)學(xué)編程,一天一篇?jiǎng)赢?huà)喂飽你!
4 5你好,小鹿!
6首先在 HTML 中找到 p 標(biāo)簽,一共有兩個(gè)地方,然后按照樣式的繼續(xù)遞歸中找具有父節(jié)點(diǎn)的 p,我們只好把第二個(gè) p 過(guò)濾掉,然后繼續(xù)向上找父節(jié)點(diǎn) div,匹配成功,然后將樣式設(shè)置到結(jié)點(diǎn)上。
我們通過(guò)上邊的動(dòng)畫(huà),可以知道為什么構(gòu)建 CSSOM 樹(shù)的時(shí)候非常耗時(shí)了,我們?cè)趯?xiě)代碼的時(shí)候可以做出優(yōu)化,所以應(yīng)該避免書(shū)寫(xiě)過(guò)于具體的 CSS 選擇器,少一些添加無(wú)意義的 HTML 標(biāo)簽,有利于提高習(xí)頁(yè)面的性能。
5.3 構(gòu)建渲染樹(shù)
我們分別將上邊生成的 DOM 和 CSSOM 樹(shù)進(jìn)行合并,生成我們的渲染樹(shù)。但是在合并的時(shí)候,并不是兩者簡(jiǎn)單的進(jìn)行結(jié)合,因?yàn)橛行┙Y(jié)點(diǎn)我們并不需要顯示,還記得有一個(gè) display:none 屬性嗎?如果某結(jié)點(diǎn)的樣式有這個(gè)屬性,就不會(huì)出現(xiàn)在渲染樹(shù)中。
5.4合成、繪制
瀏覽器在生成渲染樹(shù)的時(shí)候,就會(huì)根據(jù)渲染樹(shù)進(jìn)行布局,調(diào)用 GPU 進(jìn)行繪制,然后合成圖層,最后顯示在屏幕上。
小結(jié)
通過(guò)上邊的對(duì)瀏覽器工作原理的介紹,相信你對(duì)瀏覽器有了新的認(rèn)識(shí)和簡(jiǎn)介,但是只看上邊的知識(shí)還完全不能深入到底層,如果還想要進(jìn)行深入的對(duì)瀏覽器的工作原理進(jìn)行研究,可以英文文檔《How Browsers Work》,已經(jīng)有人把它翻譯成了中文,但是我自己又翻譯了一遍。
第一,提高自己閱讀英文文檔的能力;
第二,從中學(xué)會(huì)提取關(guān)鍵的內(nèi)容。
雖然翻譯過(guò)程中遇到很多問(wèn)題,但是相信你翻譯完之后,對(duì)你又有新的收獲和認(rèn)識(shí),更重要的是你的能力又比別人提升了 —— 更何況我這個(gè)英語(yǔ)四級(jí)沒(méi)過(guò)的人都堅(jiān)持翻譯下來(lái)了呢!
-
路由器
+關(guān)注
關(guān)注
22文章
3696瀏覽量
113432 -
DNS
+關(guān)注
關(guān)注
0文章
215瀏覽量
19771 -
瀏覽器
+關(guān)注
關(guān)注
1文章
1009瀏覽量
35231
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論