網頁開啟時都發生了什麼?我被嚇著了
在瀏覽器裡輸入網址或者點選連結,網頁開啟了……這是我們上網時再普通不過的一幕,但是如此簡單的表象背後,卻隱藏著無比複雜的技術流程。想漲漲知識嗎?往下看吧。
一個HTTP請求的過程
為了簡化我們先從一個HTTP請求開始,簡要介紹一下一個HTTP求情的網路傳輸過程,也就是所謂的“從輸入URL到頁面下載完的過程中都發生了什麼事情”。
● DNS Lookup 先獲得URL對應的IP地址
● Socket Connect 瀏覽器和伺服器建立TCP連線
● Send Request 傳送HTTP請求
● Content Download 伺服器傳送響應
如果下到物理層去講就有點耍流氓了。如果這些你還認可這幾個步驟的話,我們就來講一下這裡面存在的效能問題。
● 如果你對DNS的查詢還有印象的話現在反思一下,DNS Lookup就是為了獲取一串IP地址要和無數個DNS伺服器進行通訊,這要消耗多少時間?別忘了,你查詢完了的時候,你還沒和那邊的伺服器通訊呢。
● TCP連線要三次握手。如果伺服器很遠的話這三次握手要花多少時間?別忘了建立連線之後你還沒發請求呢。(通常到這裡0.5秒就出去了)
● 傳送HTTP請求的時候你要知道一點,就是我們的網路頻寬上行和下行通常是不一樣的,通常上行的頻寬會小一些,一個的話還好,但是現在的網頁通常都會後續請求很多資源,頻寬小的時候上行擁塞怎麼辦?別忘了已經到第三步了,伺服器還沒給你發響應呢,現在你的瀏覽器還什麼都畫不出來。
● 終於到了伺服器發響應了,不巧你訪問的這個伺服器比較忙,好幾萬個人都要這個資源,伺服器的上行頻寬也是有限的,怎麼辦?
我覺得我出了幾道還不錯的面試題。順便提一下,前兩步的延遲和網路頻寬的影響不大;後兩步加頻寬是能一定程度緩解,不過你要有錢,而且很貴。
雖說博主做過WebKit本地渲染的優化,但是深知網頁載入的主要時間還是浪費在網路通訊上,所以在這些步驟上的優化會比你在瀏覽器核心的優化省力且效果明顯。
網路方面的主要優化手段,總結一下不外乎快取、預取、壓縮、並行。以後如果再有面試問效能優化之類的問題,大家都可以照著這個思路去考慮。
下面就分階段介紹一下現有的優化手段。
DNS優化
對於DNS優化,快取無疑是最簡單粗暴且效果明顯的了。說到快取就一定要提到快取層級:
● 瀏覽器DNS快取
● 系統DNS快取
● Hosts檔案
● 各個DNS伺服器上的快取
當然DNS快取失效期通常都比較短,很多情況下都要再去查詢。為了降低使用者體驗到的延遲(注意這裡不是網路延時),預取是一個不錯的方法。
比如說你敲網址的時候還沒有敲完,但是瀏覽器根據你的歷史發現你很有可能去訪問哪個網站,就提前給你做DNS預取了,比如你打了一個“w”的時候,chrome已經幫你去找weibo.com的IP地址了。chrome使用者看一下chrome://predictors 你就知道了。
此外瀏覽器還會記錄你過去的歷史,知道每個域名下通常還會有哪些其他的連結,以便建立起網站的拓撲結構。當你訪問這個域名下的網站,它就會預先對其他連結的域名進行DNS解析。
TCP優化
看到前面的DNS的具體優化這麼繁雜,知道這簡單的一步沒那麼簡單了吧。
結果到TCP這一步優化反而簡單了,因為剛才DNS已經把IP都預先弄到了,那麼我們順著剛才的步驟再建立連線就好了。
所以在你敲第一個字母的時候,DNS解析完了就去建立連線了,這時候你可能網址還沒敲完。當你剛訪問一個網站的時候,瀏覽器刷刷刷的幫你把到別的伺服器的TCP連線給你建好。
HTTP傳輸優化
寫到這裡可能有人會想,既然已經把TCP連線建立好了,那我乾脆預取更進一步,把所有的連結內容直接預取下來不就好了,這樣我網址還沒敲完網頁就已經載入完成了。
這個想法是好的,但現實卻是殘酷的,因為要記住我們的頻寬是有限的,DNS和TCP連線量級都比較輕,對網路頻寬不會佔據太多,但是HTTP傳輸就不一樣了。如果你所有連結都去預取的話,你的頻寬很快就被佔滿了,這樣你正常的請求無法得到滿足,效能反而會嚴重下降。
快取就又出現了,提快取必提層次結構。
● PageCache 這個是最快的了,直接在記憶體中快取了現有網頁的DOM結構和渲染結果,這就是你為什麼在點前進後退的時候會這麼快。
● HTTP Cache 檔案級別的Cache存在本地的檔案系統上按照RFC2616實現。
● 代理Cache 如果是通過代理伺服器上網的話,代理伺服器通常也會按照快取標準
● CDN 一個地理上離你很近的內容伺服器,比如說你在北京請求杭州淘寶的一個圖片,結果在北京的一個CDN上有這個圖片,那麼就不用去杭州了。
● DMOC(distributed memory object caching system)CDN主要存放的是靜態資料,但是網頁中通常有很多動態的資料需要查資料庫,流量多了壓力就會很大,通常伺服器外圍還會有一層記憶體快取伺服器,專門快取這些資料庫中的物件,據《淘寶技術這10年》稱可以減少99.5%的資料庫訪問。
● Server 其實真正落在伺服器上的請求已經不多了。
大家看到這裡有沒有想到能在什麼地方再加一層快取呢?其實可以在2和3之間加,也就是在路由器上加快取。
小米路由器和搜狗合作的預取引擎其實就相當於在路由器上加一層快取款順便智慧預取一下。為什麼在這裡另起一段專門談小米呢?難不成是小米的水軍?才不是呢,是因為博主看到這個訊息的時候心都涼了,和博主的畢設撞車了有木有。
去年在360剛出隨身Wi-Fi的時候博主想到了這麼個點子,還想著把這個東西做出來之後用這個創業和360談合作,結果最近剛做完,論文也投出去了,幻想著開啟人生巔峰,顛覆行業,結果就發現小米和搜狗出了這麼個一樣的東西還都商業化了。說好的人生巔峰就這樣沒有了,早知道去年就先申請個專利了。
另一個HTTP常用的優化就是壓縮了,網路傳輸時間=訊息大小/網速。既然網速比較貴那麼就壓縮一下吧,大部分伺服器都會對HTTP訊息進行gzip壓縮。可以在Http Header中看到,具體的就不細說了。
未來協議:SPDY
上面的都是傳統做法,下面講一個未來的技術。由於HTTP協議是上個世紀制定的協議了,已經不能很好地適應現在Web的發展,所以Google提出了SPDY協議,目前是指定中的HTTP2.0標準的一個底版。
SPDY主要有下面的特點:
● 一個TCP連線上並行多個HTTP連線,減少連線的建立時間。
● 請求優先順序(目前還沒看到具體實現)。
● HTTP頭部壓縮,上文提到的HTTP壓縮是對HTTP body的壓縮,並沒有對頭部壓縮。對於小的HTTP訊息,頭部的比重還是很大的,而現在的web中存在大量小訊息。
● Server push/hint 伺服器主動推送物件(可以想象成伺服器幫客戶端預取)。
業界目前對SPDY是有贊有彈,博主也持謹慎的態度,主要在1和4上,4其實和之前提到的HTTP直接預取的矛盾點一樣,萬一推送的不需要又佔據了頻寬怎麼辦?hint到底該如何實現都有困難。
第一條潛在的風險就是TCP連線中途斷開,那麼所有的連線就全部停掉了,PC網際網路這種情況可能會少一些,但是移動網際網路中TCP連線斷開的情況還是比較常見的。
不過作為一個未來的技術,還是有必要關注一下。
相關文章
- 當你開啟網頁的時候,世界都發生了什麼(1)網頁
- 啟動vue專案時發生了什麼Vue
- 訪問網際網路時發生了什麼?
- 從輸入頁面地址到展示頁面資訊都發生了些什麼?
- go func 時發生了什麼Go
- [譯] 當你建立 Flexbox 佈局時,都發生了什麼?Flex
- K8S學習之當我們部署應用的時候都發生了什麼?K8S
- 當執行時,發生了什麼?
- 從輸入url到顯示網頁發生了什麼網頁
- 都別攔著我,我要刪庫了
- 終極版:從開機聯網到輸入一個網址期間都發生了什麼?
- 「試著讀讀 Vue 原始碼」new Vue()發生了什麼 ❓Vue原始碼
- SAP CDS view自學教程之二:當SAP CDS view被啟用時,背後發生了什麼View
- 瀏覽器從輸入網址到顯示都發生了些什麼?瀏覽器
- [webpack]原始碼解讀:命令列輸入webpack的時候都發生了什麼?Web原始碼命令列
- 成為比開發硬氣的測試人,我都經歷了什麼?
- 跟著大彬讀原始碼 - Redis 1 - 啟動服務,程式都幹了什麼?原始碼Redis
- oracle commit的時候究竟發生了什麼OracleMIT
- 當我們遊覽網頁的時候, 在輸入連結點選回車之後到看到新網頁這中間究竟發生了什麼?網頁
- new Vue發生了什麼Vue
- 你在業餘時間都開發過什麼?
- 當 Redis 發生高延遲時,到底發生了什麼Redis
- 溫故知新-輸入網址-顯示網頁-到底到底到底到底-發生了什麼?網頁
- [譯文]請求一個URL時發生了什麼
- 我學習的程式設計,都給我帶來了什麼?程式設計
- 從輸入URL到頁面載入到底發生了什麼
- 為什麼IIS網頁每天首次開啟速度很慢?網頁
- 乾貨分享丨當我們感覺開啟網頁很慢的時候,到底是什麼原因呢?網頁
- 當我呼叫了$().append()後,jQuery內部發生了什麼?APPjQuery
- 輸入完網址按下回車,到看到網頁這個過程中發生了什麼。網頁
- 一分鐘之內網際網路發生了什麼內網
- 網際網路的一秒發生了什麼——資訊圖
- 一分鐘之內 網際網路發生了什麼?
- 過去的VR元年都發生了什麼 可穿戴大事件盤點VR事件
- 網站被挾持了需要做什麼網站
- 網站開啟的速度慢原因都什麼可以這麼解決網站
- kubelet 建立 Pod 前發生了什麼?
- 猜猜體育課發生了什麼?