從輸入URL到頁面加載發(fā)生了什么

總體來說分為以下幾個過程:

  1. DNS解析

  2. TCP連接

  3. 發(fā)送HTTP請求

  4. 服務(wù)器處理請求并返回HTTP報文

  5. 瀏覽器解析渲染頁面

  6. 連接結(jié)束

具體過程

DNS解析

DNS解析的過程就是尋找哪臺機(jī)器上有你需要資源的過程。當(dāng)你在瀏覽器中輸入一個地址時,例如www.baidu.com,其實(shí)不是百度網(wǎng)站真正意義上的地址?;ヂ?lián)網(wǎng)上每一臺計算機(jī)的唯一標(biāo)識是它的IP地址,但是IP地址并不方便記憶。用戶更喜歡用方便記憶的網(wǎng)址去尋找互聯(lián)網(wǎng)上的其它計算機(jī),也就是上面提到的百度的網(wǎng)址。所以互聯(lián)網(wǎng)設(shè)計者需要在用戶的方便性與可用性方面做一個權(quán)衡,這個權(quán)衡就是一個網(wǎng)址到IP地址的轉(zhuǎn)換,這個過程就是DNS解析。它實(shí)際上充當(dāng)了一個翻譯的角色,實(shí)現(xiàn)了網(wǎng)址到IP地址的轉(zhuǎn)換。網(wǎng)址到IP地址轉(zhuǎn)換的過程是如何進(jìn)行的?

解析過程

DNS解析是一個遞歸查詢的過程。

image

上述圖片是查找www.google.com的IP地址過程。首先在本地域名服務(wù)器中查詢IP地址,如果沒有找到的情況下,本地域名服務(wù)器會向根域名服務(wù)器發(fā)送一個請求,如果根域名服務(wù)器也不存在該域名時,本地域名會向com頂級域名服務(wù)器發(fā)送一個請求,依次類推下去。直到最后本地域名服務(wù)器得到google的IP地址并把它緩存到本地,供下次查詢使用。從上述過程中,可以看出網(wǎng)址的解析是一個從右向左的過程: com -> google.com -> www.google.com。但是你是否發(fā)現(xiàn)少了點(diǎn)什么,根域名服務(wù)器的解析過程呢?事實(shí)上,真正的網(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))中:

image
  • ...
DNS負(fù)載均衡

不知道大家有沒有思考過一個問題: DNS返回的IP地址是否每次都一樣?如果每次都一樣是否說明你請求的資源都位于同一臺機(jī)器上面,那么這臺機(jī)器需要多高的性能和儲存才能滿足億萬請求呢?其實(shí)真實(shí)的互聯(lián)網(wǎng)世界背后存在成千上百臺服務(wù)器,大型的網(wǎng)站甚至更多。但是在用戶的眼中,它需要的只是處理他的請求,哪臺機(jī)器處理請求并不重要。DNS可以返回一個合適的機(jī)器的IP給用戶,例如可以根據(jù)每臺機(jī)器的負(fù)載量,該機(jī)器離用戶地理位置的距離等等,這種過程就是DNS負(fù)載均衡,又叫做DNS重定向。大家耳熟能詳?shù)腃DN(Content Delivery Network)就是利用DNS的重定向技術(shù),DNS服務(wù)器會返回一個跟用戶最接近的點(diǎn)的IP地址給用戶,CDN節(jié)點(diǎn)的服務(wù)器負(fù)責(zé)響應(yīng)用戶的請求,提供所需的內(nèi)容。在這里打個免費(fèi)的廣告,我平時使用的比較多的是七牛云的CDN(免費(fèi))儲存圖片,作為我個人博客的圖床使用。

TCP連接

HTTP協(xié)議是使用TCP作為其傳輸層協(xié)議的,當(dāng)TCP出現(xiàn)瓶頸時,HTTP也會受到影響。但由于TCP優(yōu)化這一塊我平常接觸的并不是很多,再加上大學(xué)時的計算機(jī)網(wǎng)絡(luò)的基礎(chǔ)基本上忘完,所以這一部分我也就不在這里分析了。

HTTPS協(xié)議

我不知道把HTTPS放在這個部分是否合適,但是放在這里好像又說的過去。HTTP報文是包裹在TCP報文中發(fā)送的,服務(wù)器端收到TCP報文時會解包提取出HTTP報文。但是這個過程中存在一定的風(fēng)險,HTTP報文是明文,如果中間被截取的話會存在一些信息泄露的風(fēng)險。那么在進(jìn)入TCP報文之前對HTTP做一次加密就可以解決這個問題了。HTTPS協(xié)議的本質(zhì)就是HTTP + SSL(or TLS)。在HTTP報文進(jìn)入TCP報文之前,先使用SSL對HTTP報文進(jìn)行加密。從網(wǎng)絡(luò)的層級結(jié)構(gòu)看它位于HTTP協(xié)議與TCP協(xié)議之間。

image

HTTPS過程

HTTPS在傳輸數(shù)據(jù)之前需要客戶端與服務(wù)器進(jìn)行一個握手(TLS/SSL握手),在握手過程中將確立雙方加密傳輸數(shù)據(jù)的密碼信息。TLS/SSL使用了非對稱加密,對稱加密以及hash等。具體過程請參考經(jīng)典的阮一峰先生的博客TLS/SSL握手過程。
HTTPS相比于HTTP,雖然提供了安全保證,但是勢必會帶來一些時間上的損耗,如握手和加密等過程,是否使用HTTPS需要根據(jù)具體情況在安全和性能方面做出權(quán)衡。

HTTP請求

其實(shí)這部分又可以稱為前端工程師眼中的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

eg: GET index.html HTTP/1.1

常用的方法有: GET, POST, PUT, DELETE, OPTIONS, HEAD。

TODO:

  • GET和POST有什么區(qū)別?
    傳送門

請求報頭

請求報頭允許客戶端向服務(wù)器傳遞請求的附加信息和客戶端自身的信息。
PS: 客戶端不一定特指瀏覽器,有時候也可使用Linux下的CURL命令以及HTTP客戶端測試工具等。
常見的請求報頭有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等。

image

上圖是使用Chrome開發(fā)者工具截取的對百度的HTTP請求以及響應(yīng)報文,從圖中可以看出,請求報頭中使用了Accept, Accept-Encoding, Accept-Language, Cache-Control, Connection, Cookie等字段。Accept用于指定客戶端用于接受哪些類型的信息,Accept-Encoding與Accept類似,它用于指定接受的編碼方式。Connection設(shè)置為Keep-alive用于告訴客戶端本次HTTP請求結(jié)束之后并不需要關(guān)閉TCP連接,這樣可以使下次HTTP請求使用相同的TCP通道,節(jié)省TCP連接建立的時間。

請求正文

當(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連接進(jìn)行處理,對HTTP協(xié)議進(jìn)行解析,并按照報文格式進(jìn)一步封裝成HTTP Request對象,供上層使用。這一部分工作一般是由Web服務(wù)器去進(jìn)行,我使用過的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:重定向–要完成請求必須進(jìn)行更進(jìn)一步的操作。

  • 4xx:客戶端錯誤–請求有語法錯誤或請求無法實(shí)現(xiàn)。

  • 5xx:服務(wù)器端錯誤–服務(wù)器未能實(shí)現(xiàn)合法的請求。
    平時遇到比較常見的狀態(tài)碼有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分別表示什么請自行查找)。
    狀態(tài)碼傳送門

TODO:

  • 301和302有什么區(qū)別?
    301重定向是永久的重定向,搜索引擎在抓取新內(nèi)容的同時也將舊的網(wǎng)址替換為重定向之后的網(wǎng)址。
    302重定向是臨時的重定向,搜索引擎會抓取新的內(nèi)容而保留舊的網(wǎng)址。因為服務(wù)器返回302代碼,搜索引擎認(rèn)為新的網(wǎng)址只是暫時的。

  • HTTP緩存

image

該圖是本公司對狀態(tài)碼的一個總結(jié),繪制而成的status code map,請大家參考。

響應(yīng)報頭

常見的響應(yīng)報頭字段有: Server, Connection...。

響應(yīng)報文

服務(wù)器返回給瀏覽器的文本信息,通常HTML, CSS, JS, 圖片等文件就放在這一部分。

瀏覽器解析渲染頁面

瀏覽器在收到HTML,CSS,JS文件后,它是如何把頁面呈現(xiàn)到屏幕上的?下圖對應(yīng)的就是WebKit渲染的過程。

image

瀏覽器是一個邊解析邊渲染的過程。首先瀏覽器解析HTML文件構(gòu)建DOM樹,然后解析CSS文件構(gòu)建渲染樹,等到渲染樹構(gòu)建完成后,瀏覽器開始布局渲染樹并將其繪制到屏幕上。這個過程比較復(fù)雜,涉及到兩個概念: reflow(回流)和repain(重繪)。DOM節(jié)點(diǎn)中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等,這個過程稱為relow;當(dāng)盒模型的位置,大小以及其他屬性,如顏色,字體,等確定下來之后,瀏覽器便開始繪制內(nèi)容,這個過程稱為repain。頁面在首次加載時必然會經(jīng)歷reflow和repain。reflow和repain過程是非常消耗性能的,尤其是在移動設(shè)備上,它會破壞用戶體驗,有時會造成頁面卡頓。所以我們應(yīng)該盡可能少的減少reflow和repain。

image

JS的解析是由瀏覽器中的JS解析引擎完成的。JS是單線程運(yùn)行,也就是說,在同一個時間內(nèi)只能做一件事,所有的任務(wù)都需要排隊,前一個任務(wù)結(jié)束,后一個任務(wù)才能開始。但是又存在某些任務(wù)比較耗時,如IO讀寫等,所以需要一種機(jī)制可以先執(zhí)行排在后面的任務(wù),這就是:同步任務(wù)(synchronous)和異步任務(wù)(asynchronous)。JS的執(zhí)行機(jī)制就可以看做是一個主線程加上一個任務(wù)隊列(task queue)。同步任務(wù)就是放在主線程上執(zhí)行的任務(wù),異步任務(wù)是放在任務(wù)隊列中的任務(wù)。所有的同步任務(wù)在主線程上執(zhí)行,形成一個執(zhí)行棧;異步任務(wù)有了運(yùn)行結(jié)果就會在任務(wù)隊列中放置一個事件;腳本運(yùn)行時先依次運(yùn)行執(zhí)行棧,然后會從任務(wù)隊列里提取事件,運(yùn)行任務(wù)隊列中的任務(wù),這個過程是不斷重復(fù)的,所以又叫做事件循環(huán)(Event loop)。

瀏覽器在解析過程中,如果遇到請求外部資源時,如圖像,iconfont,JS等。瀏覽器將重復(fù)1-6過程下載該資源。請求過程是異步的,并不會影響HTML文檔進(jìn)行加載,但是當(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ì)是什么。我的理解是: 將信息快速并友好的展示給用戶并能夠與用戶進(jìn)行交互??焖俚囊馑季褪窃诒M可能短的時間內(nèi)完成頁面的加載,試想一下當(dāng)你在淘寶購買東西的時候,淘寶頁面加載了10幾秒才顯示出物品,這個時候你還有心情去購買嗎?怎么快速的完成頁面的加載呢?優(yōu)雅的學(xué)院派雅虎給出了常用的一些手段,也就是我們熟悉的雅虎34條軍規(guī)。這34軍規(guī)實(shí)際上就是圍繞請求過程進(jìn)行的一些優(yōu)化方式。

如何盡快的加載資源?答案就是能不從網(wǎng)絡(luò)中加載的資源就不從網(wǎng)絡(luò)中加載,當(dāng)我們合理使用緩存,將資源放在瀏覽器端,這是最快的方式。如果資源必須從網(wǎng)絡(luò)中加載,則要考慮縮短連接時間,即DNS優(yōu)化部分;減少響應(yīng)內(nèi)容大小,即對內(nèi)容進(jìn)行壓縮。另一方面,如果加載的資源數(shù)比較少的話,也可以快速的響應(yīng)用戶。當(dāng)資源到達(dá)瀏覽器之后,瀏覽器開始進(jìn)行解析渲染,瀏覽器中最耗時的部分就是reflow,所以圍繞這一部分就是考慮如何減少reflow的次數(shù)。

總結(jié)

寫這篇文章真的非常糾結(jié),前前后后斷斷續(xù)續(xù)寫了兩個星期,因為涉及到的東西比較多,再加上有些東西記憶的沒有那么清晰了,所以不好下筆。所涉及到的大部分內(nèi)容,也基本上是一筆帶過,只是給讀者一個淺顯的認(rèn)知,當(dāng)遇到相關(guān)的問題時,知道如何去查詢。大家可以當(dāng)成一篇Web開發(fā)的科普類文章去閱讀。

另外在這里為公司的產(chǎn)品打個廣告,在Chrome store中搜索DHC,這是一款超級好用的Web客戶端工具,囊括了很多的功能: 報文分析,API測試等等,可謂說是WEB工程師必備工具。

HTTP狀態(tài)碼

100  Continue  繼續(xù),一般在發(fā)送post請求時,已發(fā)送了http header之后服務(wù)端將返回此信息,表示確認(rèn),之后發(fā)送具體參數(shù)信息

200  OK   正常返回信息

201  Created  請求成功并且服務(wù)器創(chuàng)建了新的資源

202  Accepted  服務(wù)器已接受請求,但尚未處理

301  Moved Permanently  請求的網(wǎng)頁已永久移動到新位置。

302 Found  臨時性重定向。

303 See Other  臨時性重定向,且總是使用 GET 請求新的 URI。

304  Not Modified  自從上次請求后,請求的網(wǎng)頁未修改過。

400 Bad Request  服務(wù)器無法理解請求的格式,客戶端不應(yīng)當(dāng)嘗試再次使用相同的內(nèi)容發(fā)起請求。

401 Unauthorized  請求未授權(quán)。

403 Forbidden  禁止訪問。

404 Not Found  找不到如何與 URI 相匹配的資源。

500 Internal Server Error  最常見的服務(wù)器端錯誤。

503 Service Unavailable 服務(wù)器端暫時無法處理請求(可能是過載或維護(hù))。

鏈接:http://www.itdecent.cn/p/a877684a4cdd

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容