從輸入url到頁面載入發生了什麼
最近在進行前端面試方面的一些準備,看了網上許多相關的文章,發現有乙個問題始終繞不開: 在瀏覽器中輸入url到整個頁面顯示在使用者面前時這個過程中到底發生了什麼。仔細思考這個問題,發現確實很深,這個過程涉及到的東西很多。這個問題的回答真的能夠很好的考驗乙個web工程師的水平,於是我自問自答一番。
總體來說分為以下幾個過程:
dns解析
tcp連線
傳送http請求
伺服器處理請求並返回http報文
瀏覽器解析渲染頁面
連線結束
解析過程
dns解析是乙個遞迴查詢的過程。
首先在本地網域名稱伺服器中查詢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伺服器快取,根網域名稱伺服器快取,頂級網域名稱伺服器快取,主網域名稱伺服器快取。
在你的chrome瀏覽器中輸入:chrome://dns/,你可以看到chrome瀏覽器的dns快取。
系統快取主要存在/etc/hosts(linux系統)中:
dns負載均衡
不知道大家有沒有思考過乙個問題: dns返回的ip位址是否每次都一樣?如果每次都一樣是否說明你請求的資源都位於同一臺機器上面,那麼這台機器需要多高的效能和儲存才能滿足億萬請求呢?其實真實的網際網路世界背後存在成千上百臺伺服器,大型的**甚至更多。但是在使用者的眼中,它需要的只是處理他的請求,哪台機器處理請求並不重要。dns可以返回乙個合適的機器的ip給使用者,例如可以根據每台機器的負載量,該機器離使用者地理位置的距離等等,這種過程就是dns負載均衡,又叫做dns重定向。大家耳熟能詳的cdn(content delivery network)就是利用dns的重定向技術,dns伺服器會返回乙個跟使用者最接近的點的ip位址給使用者,cdn節點的伺服器負責響應使用者的請求,提供所需的內容。在這裡打個免費的廣告,我平時使用的比較多的是七牛雲的cdn(免費)儲存,作為我個人部落格的圖床使用。
tcp連線
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請求的過程就是構建http請求報文並通過tcp協議中傳送到伺服器指定埠(http協議80/8080, https協議443)。http請求報文是由三部分組成:
請求行,
請求報頭和請求正文。
請求行格式如下:
常用的方法有: get, post, put, delete, options, head。
todo:
get和post有什麼區別?
傳送門請求報頭
請求報頭允許客戶端向伺服器傳遞請求的附加資訊和客戶端自身的資訊。
ps: 客戶端不一定特指瀏覽器,有時候也可使用linux下的curl命令以及http客戶端測試工具等。
常見的請求報頭有: accept, accept-charset, accept-encoding, accept-language, content-type, authorization, cookie, user-agent等。
伺服器處理請求並返回http報文
自然而然這部分對應的就是後端工程師眼中的http。後端從在固定的埠接收到tcp報文開始,這一部分對應於程式語言中的socket。它會對tcp連線進行處理,對http協議進行解析,並按照報文格式進一步封裝成http request物件,供上層使用。這一部分工作一般是由web伺服器去進行,我使用過的web伺服器有tomcat, jetty和netty等等。
http響應報文也是由三部分組成:
狀態碼,
響應報頭和響應報文。
狀態碼狀態碼是由3位數組成,第乙個數字定義了響應的類別,且有五種可能取值:
1xx:指示資訊–表示請求已接收,繼續處理。
2xx:成功–表示請求已被成功接收、理解、接受。
3xx:重定向–要完成請求必須進行更進一步的操作。
4xx:客戶端錯誤–請求有語法錯誤或請求無法實現。
5xx:伺服器端錯誤–伺服器未能實現合法的請求。
平時遇到比較常見的狀態碼有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分別表示什麼請自行查詢)。
狀態碼傳送門
todo:
301和302有什麼區別?
301重定向是永久的重定向,搜尋引擎在抓取新內容的同時也將舊的**替換為重定向之後的**。
302重定向是臨時的重定向,搜尋引擎會抓取新的內容而保留舊的**。因為伺服器返回302**,搜尋引擎認為新的**只是暫時的。
http快取
響應報頭
常見的響應報頭欄位有: server, connection…。
響應報文
伺服器返回給瀏覽器的文字資訊,通常html, css, js, 等檔案就放在這一部分。
瀏覽器解析渲染頁面
瀏覽器在收到html,css,js檔案後,它是如何把頁面呈現到螢幕上的?下圖對應的就是webkit渲染的過程。
瀏覽器是乙個邊解析邊渲染的過程。首先瀏覽器解析html檔案構建dom樹,然後解析css檔案構建渲染樹,等到渲染樹構建完成後,瀏覽器開始布局渲染樹並將其繪製到螢幕上。這個過程比較複雜,涉及到兩個概念: reflow(回流)和repain(重繪)。dom節點中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等,這個過程稱為relow;當盒模型的位置,大小以及其他屬性,如顏色,字型,等確定下來之後,瀏覽器便開始繪製內容,這個過程稱為repain。頁面在首次載入時必然會經歷reflow和repain。reflow和repain過程是非常消耗效能的,尤其是在移動裝置上,它會破壞使用者體驗,有時會造成頁面卡頓。所以我們應該盡可能少的減少reflow和repain。
web優化
上面部分主要介紹了一次完整的請求對應的過程,了解該過程的目的無非就是為了web優化。在談到web優化之前,我們回到乙個更原始的問題,web前端的本質是什麼。我的理解是: 將資訊快速並友好的展示給使用者並能夠與使用者進行互動。快速的意思就是在盡可能短的時間內完成頁面的載入,試想一下當你在**購買東西的時候,**頁面載入了10幾秒才顯示出物品,這個時候你還有心情去購買嗎?怎麼快速的完成頁面的載入呢?優雅的學院派雅虎給出了常用的一些手段,也就是我們熟悉的雅虎34條軍規。這34軍規實際上就是圍繞請求過程進行的一些優化方式。
如何盡快的載入資源?答案就是能不從網路中載入的資源就不從網路中載入,當我們合理使用快取,將資源放在瀏覽器端,這是最快的方式。如果資源必須從網路中載入,則要考慮縮短連線時間,即dns優化部分;減少響應內容大小,即對內容進行壓縮。另一方面,如果載入的資源數比較少的話,也可以快速的響應使用者。當資源到達瀏覽器之後,瀏覽器開始進行解析渲染,瀏覽器中最耗時的部分就是reflow,所以圍繞這一部分就是考慮如何減少reflow的次數。
從輸入 URL 到瀏覽器渲染完成
首先,判斷是不是https的,如果是,則https其實是http ssl tls 兩部分組成,也就是在http上又加了一層處理加密資訊的模組。服務端和客戶端的資訊傳輸都會通過tls進行加密,所以傳輸的資料都是加密後的資料。進行三次握手,建立tcp連線。第一次握手 建立連線。客戶端傳送連線請求報文段,...
從URL輸入瀏覽器到頁面顯示全過程
第一步 網域名稱解析,將網域名稱解析成對應ip。按先後順序檢視 1.瀏覽器快取。2.本機的host檔案。linux etc hosts 3.路由器快取。4.本地dns伺服器,遞迴查詢對應ip。本地網域名稱伺服器就以dns客戶的身份,向其他根網域名稱伺服器繼續發出查詢請求報文,而不是讓該主機自己進行下...
從瀏覽器輸入url到頁面展示出來的過程
我們可以把這個過程分為兩個部分來分析 1.使用者輸入url 到 瀏覽器拿到服務端返回的資料 2.瀏覽器拿到資料 到 瀏覽器成功渲染拿到的資料 第一部分 1.使用者輸入url位址 在使用者輸入url的時候,瀏覽器會從歷史記錄 書籤等地方找輸入的字串可能對應的url然後給出智慧型提示。2.dns解析 使...