總體來說分為以下幾個過程:
-
DNS
解析 -
TCP
連接 - 發(fā)送
HTTP
請求 - 服務(wù)器處理請求并返回
HTTP
報文 - 瀏覽器解析渲染頁面
- 連接結(jié)束
具體過程
DNS解析
DNS
解析的過程就是尋找哪臺機器上有你需要資源的過程。當(dāng)你在瀏覽器中輸入一個地址時异吻,例如www.baidu.com
裹赴,其實不是百度網(wǎng)站真正意義上的地址【骼耍互聯(lián)網(wǎng)上每一臺計算機的唯一標(biāo)識是它的IP
地址棋返,但是IP
地址并不方便記憶。用戶更喜歡用方便記憶的網(wǎng)址去尋找互聯(lián)網(wǎng)上的其它計算機雷猪,也就是上面提到的百度的網(wǎng)址睛竣。
所以互聯(lián)網(wǎng)設(shè)計者需要在用戶的方便性與可用性方面做一個權(quán)衡,這個權(quán)衡就是一個網(wǎng)址到IP地址的轉(zhuǎn)換求摇,這個過程就是DNS解析射沟。它實際上充當(dāng)了一個翻譯的角色,實現(xiàn)了網(wǎng)址到IP
地址的轉(zhuǎn)換与境。網(wǎng)址到IP
地址轉(zhuǎn)換的過程是如何進行的?
解析過程
DNS
解析是一個遞歸查詢的過程验夯。
首先在本地域名服務(wù)器中查詢IP
地址,如果沒有找到的情況下摔刁,本地域名服務(wù)器會向根域名服務(wù)器發(fā)送一個請求挥转,如果根域名服務(wù)器也不存在該域名時,本地域名會向com
頂級域名服務(wù)器發(fā)送一個請求簸搞,依次類推下去扁位。直到最后本地域名服務(wù)器得到google
的IP地址并把它緩存到本地,供下次查詢使用趁俊。
從上述過程中域仇,可以看出網(wǎng)址的解析是一個從右向左的過程: com
-> google.com
-> www.google.com
。但是你是否發(fā)現(xiàn)少了點什么寺擂,根域名服務(wù)器的解析過程呢暇务?
事實上,真正的網(wǎng)址是www.google.com.
怔软,并不是我多打了一個.
垦细,這個.
對應(yīng)的就是根域名服務(wù)器,默認(rèn)情況下所有的網(wǎng)址的最后一位都是.
挡逼,既然是默認(rèn)情況下括改,為了方便用戶,通常都會省略家坎,瀏覽器在請求DNS
的時候會自動加上嘱能,所有網(wǎng)址真正的解析過程為: .
-> .com
-> google.com.
-> www.google.com.
吝梅。
DNS優(yōu)化
了解了DNS
的過程,可以為我們帶來哪些惹骂?
上文中請求到google
的IP地址時苏携,經(jīng)歷了8個步驟,這個過程中存在多個請求(同時存在UDP
和TCP
請求对粪,為什么有兩種請求方式右冻,請自行查找)。如果每次都經(jīng)過這么多步驟著拭,是否太耗時間纱扭?如何減少該過程的步驟呢?那就是DNS緩存茫死。
DNS緩存
DNS
存在著多級緩存跪但,從離瀏覽器的距離排序的話,有以下幾種: 瀏覽器緩存峦萎,系統(tǒng)緩存,路由器緩存忆首,IPS服務(wù)器緩存爱榔,根域名服務(wù)器緩存,頂級域名服務(wù)器緩存糙及,主域名服務(wù)器緩存**详幽。
在你的chrome
瀏覽器中輸入:chrome://dns/
,你可以看到chrome
瀏覽器的DNS
緩存浸锨。
系統(tǒng)緩存主要存在/etc/hosts
(Linux
系統(tǒng))中唇聘。
DNS負(fù)載均衡
不知道大家有沒有思考過一個問題: DNS
返回的IP地址是否每次都一樣?
如果每次都一樣是否說明你請求的資源都位于同一臺機器上面柱搜,那么這臺機器需要多高的性能和儲存才能滿足億萬請求呢迟郎?其實真實的互聯(lián)網(wǎng)世界背后存在成千上百臺服務(wù)器,大型的網(wǎng)站甚至更多聪蘸。但是在用戶的眼中宪肖,它需要的只是處理他的請求,哪臺機器處理請求并不重要健爬。
DNS
可以返回一個合適的機器的IP
給用戶控乾,例如可以根據(jù)每臺機器的負(fù)載量,該機器離用戶地理位置的距離等等娜遵,這種過程就是DNS負(fù)載均衡蜕衡,又叫做DNS重定向。
大家耳熟能詳?shù)?code>CDN(Content Delivery Network
)就是利用DNS
的重定向技術(shù)设拟,DNS
服務(wù)器會返回一個跟用戶最接近的點的IP
地址給用戶慨仿,CDN
節(jié)點的服務(wù)器負(fù)責(zé)響應(yīng)用戶的請求鸽扁,提供所需的內(nèi)容。
TCP連接
HTTP
協(xié)議是使用TCP
作為其傳輸層協(xié)議的镶骗,當(dāng)TCP
出現(xiàn)瓶頸時桶现,HTTP
也會受到影響。但由于TCP
優(yōu)化這一塊我平常接觸的并不是很多鼎姊,再加上大學(xué)時的計算機網(wǎng)絡(luò)的基礎(chǔ)基本上忘完骡和,所以這一部分我也就不在這里分析了。
HTTPS協(xié)議
我不知道把HTTPS
放在這個部分是否合適相寇,但是放在這里好像又說的過去慰于。HTTP
報文是包裹在TCP
報文中發(fā)送的,服務(wù)器端收到TCP
報文時會解包提取出HTTP
報文唤衫。但是這個過程中存在一定的風(fēng)險婆赠,HTTP
報文是明文,如果中間被截取的話會存在一些信息泄露的風(fēng)險佳励。那么在進入TCP
報文之前對HTTP
做一次加密就可以解決這個問題了休里。
HTTPS
協(xié)議的本質(zhì)就是HTTP
+ SSL
(or TLS
)。在HTTP
報文進入TCP
報文之前赃承,先使用SSL
對HTTP
報文進行加密妙黍。從網(wǎng)絡(luò)的層級結(jié)構(gòu)看它位于HTTP
協(xié)議與TCP
協(xié)議之間。
HTTPS過程
HTTPS
在傳輸數(shù)據(jù)之前需要客戶端與服務(wù)器進行一個握手(TLS/SSL
握手)瞧剖,在握手過程中將確立雙方加密傳輸數(shù)據(jù)的密碼信息拭嫁。TLS/SSL
使用了非對稱加密,對稱加密以及hash
等抓于。
HTTPS
相比于HTTP
做粤,雖然提供了安全保證,但是勢必會帶來一些時間上的損耗捉撮,如握手和加密等過程怕品,是否使用HTTPS
需要根據(jù)具體情況在安全和性能方面做出權(quán)衡。
HTTP請求
其實這部分又可以稱為前端工程師眼中的HTTP
呕缭,它主要發(fā)生在客戶端堵泽。發(fā)送HTTP
請求的過程就是構(gòu)建HTTP
請求報文并通過TCP
協(xié)議中發(fā)送到服務(wù)器指定端口(HTTP
協(xié)議80/8080
, HTTPS
協(xié)議443
)。
HTTP
請求報文是由三部分組成: 請求行, 請求報頭和請求正文恢总。
請求行格式如下:
Method Request-URL HTTP-Version CRLF
例:
GET index.html HTTP/1.1
常用的方法有: GET
, POST
, PUT
,DELETE
, OPTIONS
, HEAD
迎罗。
請求報頭
請求報頭允許客戶端向服務(wù)器傳遞請求的附加信息和客戶端自身的信息。PS: 客戶端不一定特指瀏覽器片仿,有時候也可使用Linux
下的CURL
命令以及HTTP
客戶端測試工具等纹安。
常見的請求報頭有: Accept
, Accept-Charset
, Accept-Encoding
, Accept-Language
, Content-Type
, Authorization
, Cookie
, User-Agent
等。
請求正文
當(dāng)使用POST
,PUT
等方法時,通常需要客戶端向服務(wù)器傳遞數(shù)據(jù)厢岂。這些數(shù)據(jù)就儲存在請求正文中光督。在請求包頭中有一些與請求正文相關(guān)的信息。例如: 現(xiàn)在的Web
應(yīng)用通常采用Rest
架構(gòu)塔粒,請求的數(shù)據(jù)格式一般為json
结借。這時就需要設(shè)置Content-Type: application/json
。
服務(wù)器處理請求并返回HTTP
報文
自然而然這部分對應(yīng)的就是后端工程師眼中的HTTP
卒茬。后端從在固定的端口接收到TCP
報文開始船老,這一部分對應(yīng)于編程語言中的socket
。它會對TCP
連接進行處理圃酵,對HTTP
協(xié)議進行解析柳畔,并按照報文格式進一步封裝成HTTP Request
對象,供上層使用郭赐。這一部分工作一般是由Web
服務(wù)器去進行薪韩,我使用過的Web
服務(wù)器有Tomcat
, Jetty
和Netty
等等。
HTTP
響應(yīng)報文也是由三部分組成: 狀態(tài)碼, 響應(yīng)報頭和響應(yīng)報文捌锭。
狀態(tài)碼
狀態(tài)碼是由3位數(shù)組成俘陷,第一個數(shù)字定義了響應(yīng)的類別,且有五種可能取值:
1xx
:指示信息–表示請求已接收舀锨,繼續(xù)處理岭洲。
2xx
:成功–表示請求已被成功接收、理解坎匿、接受。
3xx
:重定向–要完成請求必須進行更進一步的操作雷激。
4xx
:客戶端錯誤–請求有語法錯誤或請求無法實現(xiàn)替蔬。
5xx
:服務(wù)器端錯誤–服務(wù)器未能實現(xiàn)合法的請求。
響應(yīng)報頭
常見的響應(yīng)報頭字段有: Server
,Connection
...屎暇。
響應(yīng)報文
服務(wù)器返回給瀏覽器的文本信息承桥,通常HTML
,CSS
, JS
, 圖片等文件就放在這一部分。
瀏覽器解析渲染頁面
瀏覽器在收到HTML
,CSS
,JS
文件后根悼,它是如何把頁面呈現(xiàn)到屏幕上的凶异?
瀏覽器是一個邊解析邊渲染的過程。首先瀏覽器解析HTML
文件構(gòu)建DOM
樹挤巡,然后解析CSS
文件構(gòu)建Style Rules
剩彬,通過Attachment
過程之后生成了渲染樹,瀏覽器開始布局渲染樹并將其繪制到屏幕上矿卑。這個過程比較復(fù)雜喉恋,涉及到兩個概念: reflow
(回流)和repain
(重繪)。
DOM
節(jié)點中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等轻黑,這個過程稱為relow
;當(dāng)盒模型的位置,大小以及其他屬性確定下來之后糊肤,瀏覽器便開始繪制內(nèi)容,這個過程稱為repain
氓鄙。頁面在首次加載時必然會經(jīng)歷reflow
和repain
馆揉。
reflow
和repain
過程是非常消耗性能的,尤其是在移動設(shè)備上抖拦,它會破壞用戶體驗升酣,有時會造成頁面卡頓。所以我們應(yīng)該盡可能少的減少reflow
和repain
蟋座。
JS
的解析是由瀏覽器中的JS
解析引擎完成的拗踢。JS
是單線程運行,也就是說向臀,在同一個時間內(nèi)只能做一件事巢墅,所有的任務(wù)都需要排隊,前一個任務(wù)結(jié)束券膀,后一個任務(wù)才能開始君纫。
但是又存在某些任務(wù)比較耗時,如IO
讀寫等芹彬,所以需要一種機制可以先執(zhí)行排在后面的任務(wù)蓄髓,這就是:同步任務(wù)(synchronous
)和異步任務(wù)(asynchronous
)。
JS
的執(zhí)行機制就可以看做是一個主線程加上一個任務(wù)隊列(task queue
)舒帮。同步任務(wù)就是放在主線程上執(zhí)行的任務(wù)会喝,異步任務(wù)是放在任務(wù)隊列中的任務(wù)。所有的同步任務(wù)在主線程上執(zhí)行玩郊,形成一個執(zhí)行棧;異步任務(wù)有了運行結(jié)果就會在任務(wù)隊列中放置一個事件肢执;腳本運行時先依次運行執(zhí)行棧,然后會從任務(wù)隊列里提取事件译红,運行任務(wù)隊列中的任務(wù)预茄,這個過程是不斷重復(fù)的,所以又叫做事件循環(huán)(Event loop
)侦厚。
瀏覽器在解析過程中耻陕,如果遇到請求外部資源時,如圖像,iconfont
,JS
等刨沦。瀏覽器將需要下載該資源诗宣。請求過程是異步的,并不會影響HTML
文檔進行加載已卷,但是當(dāng)文檔加載過程中遇到JS
文件梧田,HTML
文檔會掛起渲染過程淳蔼,不僅要等到文檔中JS
文件加載完畢還要等待解析執(zhí)行完畢,才會繼續(xù)HTML
的渲染過程裁眯。原因是因為JS
有可能修改DOM
結(jié)構(gòu)鹉梨,這就意味著JS
執(zhí)行完成前,后續(xù)所有資源的下載是沒有必要的穿稳,這就是JS
阻塞后續(xù)資源下載的根本原因存皂。CSS
文件的加載不影響JS
文件的加載,但是卻影響JS
文件的執(zhí)行逢艘。JS
代碼執(zhí)行前瀏覽器必須保證CSS
文件已經(jīng)下載并加載完畢旦袋。
Web優(yōu)化
上面部分主要介紹了一次完整的請求對應(yīng)的過程,了解該過程的目的無非就是為了Web
優(yōu)化它改。在談到Web
優(yōu)化之前疤孕,我們回到一個更原始的問題,Web
前端的本質(zhì)是什么央拖。
我的理解是: 將信息快速并友好的展示給用戶并能夠與用戶進行交互祭阀。快速的意思就是在盡可能短的時間內(nèi)完成頁面的加載鲜戒,試想一下當(dāng)你在淘寶購買東西的時候专控,淘寶頁面加載了10
幾秒才顯示出物品,這個時候你還有心情去購買嗎遏餐?怎么快速的完成頁面的加載呢伦腐?
如何盡快的加載資源?答案就是能不從網(wǎng)絡(luò)中加載的資源就不從網(wǎng)絡(luò)中加載失都,當(dāng)我們合理使用緩存柏蘑,將資源放在瀏覽器端,這是最快的方式粹庞。如果資源必須從網(wǎng)絡(luò)中加載辩越,則要考慮縮短連接時間,即DNS
優(yōu)化部分;減少響應(yīng)內(nèi)容大小信粮,即對內(nèi)容進行壓縮。另一方面趁啸,如果加載的資源數(shù)比較少的話强缘,也可以快速的響應(yīng)用戶。當(dāng)資源到達(dá)瀏覽器之后不傅,瀏覽器開始進行解析渲染旅掂,瀏覽器中最耗時的部分就是reflow
,所以圍繞這一部分就是考慮如何減少reflow
的次數(shù)访娶。
轉(zhuǎn)自
前端經(jīng)典面試題: 從輸入URL到頁面加載發(fā)生了什么商虐?