從輸入URL到頁面載入發生了什麼

2022-05-17 17:01:07 字數 4407 閱讀 3770

最近在進行前端面試方面的一些準備,看了網上許多相關的文章,發現有乙個問題始終繞不開: 在瀏覽器中輸入url到整個頁面顯示在使用者面前時這個過程中到底發生了什麼。仔細思考這個問題,發現確實很深,這個過程涉及到的東西很多。這個問題的回答真的能夠很好的考驗乙個web工程師的水平,於是我自問自答一番。

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

dns解析

tcp連線

傳送http請求

伺服器處理請求並返回http報文

瀏覽器解析渲染頁面

連線結束

解析過程

dns解析是乙個遞迴查詢的過程。

上述是查詢www.google.com的ip位址過程。首先在本地網域名稱伺服器中查詢ip位址,如果沒有找到的情況下,本地網域名稱伺服器會向根網域名稱伺服器傳送乙個請求,如果根網域名稱伺服器也不存在該網域名稱時,本地網域名稱會向com頂級網域名稱伺服器傳送乙個請求,依次類推下去。直到最後本地網域名稱伺服器得到google的ip位址並把它快取到本地,供下次查詢使用。從上述過程中,可以看出**的解析是乙個從右向左的過程: com -> google.com -> www.google.com。但是你是否發現少了點什麼,根網域名稱伺服器的解析過程呢?事實上,真正的**是www.google.com.,並不是我多打了乙個.,這個.對應的就是根網域名稱伺服器,預設情況下所有的**的最後一位都是.,既然是預設情況下,為了方便使用者,通常都會省略,瀏覽器在請求dns的時候會自動加上,所有**真正的解析過程為: . -> .com -> google.com. -> www.google.com.。

dns優化

了解了dns的過程,可以為我們帶來哪些?上文中請求到google的ip位址時,經歷了8個步驟,這個過程中存在多個請求(同時存在udp和tcp請求,為什麼有兩種請求方式,請自行查詢)。如果每次都經過這麼多步驟,是否太耗時間?如何減少該過程的步驟呢?那就是dns快取。

dns快取

dns存在著多級快取,從離瀏覽器的距離排序的話,有以下幾種: 瀏覽器快取,系統快取,路由器快取,ips伺服器快取,根網域名稱伺服器快取,頂級網域名稱伺服器快取,主網域名稱伺服器快取。

dns負載均衡

不知道大家有沒有思考過乙個問題: dns返回的ip位址是否每次都一樣?如果每次都一樣是否說明你請求的資源都位於同一臺機器上面,那麼這台機器需要多高的效能和儲存才能滿足億萬請求呢?其實真實的網際網路世界背後存在成千上百臺伺服器,大型的**甚至更多。但是在使用者的眼中,它需要的只是處理他的請求,哪台機器處理請求並不重要。dns可以返回乙個合適的機器的ip給使用者,例如可以根據每台機器的負載量,該機器離使用者地理位置的距離等等,這種過程就是dns負載均衡,又叫做dns重定向。大家耳熟能詳的cdn(content delivery network)就是利用dns的重定向技術,dns伺服器會返回乙個跟使用者最接近的點的ip位址給使用者,cdn節點的伺服器負責響應使用者的請求,提供所需的內容。在這裡打個免費的廣告,我平時使用的比較多的是七牛雲的cdn(免費)儲存,作為我個人部落格的圖床使用。

http協議是使用tcp作為其傳輸層協議的,當tcp出現瓶頸時,http也會受到影響。但由於tcp優化這一塊我平常接觸的並不是很多,再加上大學時的計算機網路的基礎基本上忘完,所以這一部分我也就不在這裡分析了。

https協議

我不知道把https放在這個部分是否合適,但是放在這裡好像又說的過去。http報文是包裹在tcp報文中傳送的,伺服器端收到tcp報文時會解包提取出http報文。但是這個過程中存在一定的風險,http報文是明文,如果中間被擷取的話會存在一些資訊洩露的風險。那麼在進入tcp報文之前對http做一次加密就可以解決這個問題了。https協議的本質就是http + ssl(or tls)。在http報文進入tcp報文之前,先使用ssl對http報文進行加密。從網路的層級結構看它位於http協議與tcp協議之間。

https過程

https在傳輸資料之前需要客戶端與伺服器進行乙個握手(tls/ssl握手),在握手過程中將確立雙方加密傳輸資料的密碼資訊。tls/ssl使用了非對稱加密,對稱加密以及hash等。具體過程請參考經典的阮一峰先生的部落格tls/ssl握手過程。

https相比於http,雖然提供了安全保證,但是勢必會帶來一些時間上的損耗,如握手和加密等過程,是否使用https需要根據具體情況在安全和效能方面做出權衡。

其實這部分又可以稱為前端工程師眼中的http,它主要發生在客戶端。傳送http請求的過程就是構建http請求報文並通過tcp協議中傳送到伺服器指定埠(http協議80/8080, https協議443)。http請求報文是由三部分組成:請求行,請求報頭請求正文

請求行格式如下:

eg: get index.html http/1.1
常用的方法有: get, post, put, delete, options, head。

todo:

請求報頭

請求報頭允許客戶端向伺服器傳遞請求的附加資訊和客戶端自身的資訊。

ps: 客戶端不一定特指瀏覽器,有時候也可使用linux下的curl命令以及http客戶端測試工具等。

常見的請求報頭有: accept, accept-charset, accept-encoding, accept-language, content-type, authorization, cookie, user-agent等。

請求正文自然而然這部分對應的就是後端工程師眼中的http。後端從在固定的埠接收到tcp報文開始,這一部分對應於程式語言中的socket。它會對tcp連線進行處理,對http協議進行解析,並按照報文格式進一步封裝成http request物件,供上層使用。這一部分工作一般是由web伺服器去進行,我使用過的web伺服器有tomcat, jetty和netty等等。

http響應報文也是由三部分組成:狀態碼,響應報頭響應報文

狀態碼狀態碼是由3位數組成,第乙個數字定義了響應的類別,且有五種可能取值:

todo:

該圖是本公司對狀態碼的乙個總結,繪製而成的status code map,請大家參考。

響應報頭

常見的響應報頭欄位有: server, connection…。

響應報文

伺服器返回給瀏覽器的文字資訊,通常html, css, js, 等檔案就放在這一部分。

瀏覽器在收到html,css,js檔案後,它是如何把頁面呈現到螢幕上的?下圖對應的就是webkit渲染的過程。

瀏覽器是乙個邊解析邊渲染的過程。首先瀏覽器解析html檔案構建dom樹,然後解析css檔案構建渲染樹,等到渲染樹構建完成後,瀏覽器開始布局渲染樹並將其繪製到螢幕上。這個過程比較複雜,涉及到兩個概念: reflow(回流)和repain(重繪)。dom節點中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等,這個過程稱為relow;當盒模型的位置,大小以及其他屬性,如顏色,字型,等確定下來之後,瀏覽器便開始繪製內容,這個過程稱為repain。頁面在首次載入時必然會經歷reflow和repain。reflow和repain過程是非常消耗效能的,尤其是在移動裝置上,它會破壞使用者體驗,有時會造成頁面卡頓。所以我們應該盡可能少的減少reflow和repain。

js的解析是由瀏覽器中的js解析引擎完成的。js是單執行緒執行,也就是說,在同乙個時間內只能做一件事,所有的任務都需要排隊,前乙個任務結束,後乙個任務才能開始。但是又存在某些任務比較耗時,如io讀寫等,所以需要一種機制可以先執行排在後面的任務,這就是:同步任務(synchronous)和非同步任務(asynchronous)。js的執行機制就可以看做是乙個主線程加上乙個任務佇列(task queue)。同步任務就是放在主線程上執行的任務,非同步任務是放在任務佇列中的任務。所有的同步任務在主線程上執行,形成乙個執行棧;非同步任務有了執行結果就會在任務佇列中放置乙個事件;指令碼執行時先依次執行執行棧,然後會從任務佇列裡提取事件,執行任務佇列中的任務,這個過程是不斷重複的,所以又叫做事件迴圈(event loop)。

上面部分主要介紹了一次完整的請求對應的過程,了解該過程的目的無非就是為了web優化。在談到web優化之前,我們回到乙個更原始的問題,web前端的本質是什麼。我的理解是: 將資訊快速並友好的展示給使用者並能夠與使用者進行互動。快速的意思就是在盡可能短的時間內完成頁面的載入,試想一下當你在**購買東西的時候,**頁面載入了10幾秒才顯示出物品,這個時候你還有心情去購買嗎?怎麼快速的完成頁面的載入呢?優雅的學院派雅虎給出了常用的一些手段,也就是我們熟悉的雅虎34條軍規。這34軍規實際上就是圍繞請求過程進行的一些優化方式。

如何盡快的載入資源?答案就是能不從網路中載入的資源就不從網路中載入,當我們合理使用快取,將資源放在瀏覽器端,這是最快的方式。如果資源必須從網路中載入,則要考慮縮短連線時間,即dns優化部分;減少響應內容大小,即對內容進行壓縮。另一方面,如果載入的資源數比較少的話,也可以快速的響應使用者。當資源到達瀏覽器之後,瀏覽器開始進行解析渲染,瀏覽器中最耗時的部分就是reflow,所以圍繞這一部分就是考慮如何減少reflow的次數。

從輸入URL到頁面載入,發生了什麼

整理之前的筆記時,發現之前的掌握的東西尚差的太遠,就仔細查詢了這個問題。總體來說,可以分為一下幾個部分 1.dns解析 2.tcp連線 3.傳送http請求 4.伺服器處理請求並返回http報文 5.瀏覽器解析渲染頁面 6.連線結束 dns解析是將網域名稱轉換成ip的過程,從使用者在瀏覽器位址列輸入...

從輸入URL到頁面載入發生了什麼

最近在進行前端面試方面的一些準備,看了網上許多相關的文章,發現有乙個問題始終繞不開 在瀏覽器中輸入url到整個頁面顯示在使用者面前時這個過程中到底發生了什麼。仔細思考這個問題,發現確實很深,這個過程涉及到的東西很多。這個問題的回答真的能夠很好的考驗乙個web工程師的水平,於是我自問自答一番。總體來說...

從輸入URL到頁面載入發生了什麼

tcp連線 傳送http請求 伺服器處理請求並返回http報文 瀏覽器解析渲染頁面 連線結束 系統快取主要存在 etc hosts linux系統 中 http請求 2xx 成功 表示請求已被成功接收 理解 接受。3xx 重定向 要完成請求必須進行更進一步的操作。4xx 客戶端錯誤 請求有語法錯誤或...