之前咱們談性能優化,關鍵指標是頁面 PLC(加載時間)
,簡單的定義就是:瀏覽器中的加載旋轉圖標中止時間。html
而當前,咱們構建的再也不是一個網頁而是一個動態、交互的應用。如今咱們來看看網絡性能在其優化歷程中是如何一步步的提升的。web
爲何 "樣式在上,腳本在下" 是最佳實踐?瀏覽器
要回答這個問題,咱們得首先回顧一下瀏覽器的架構,瞭解解析、佈局和腳本之間如何相互配合在屏幕上繪製出像素來。性能優化
瀏覽器在解析 HTML
文檔的基礎上構建 DOM
,同時也會 CSS 對象模型,這兩個模型共同建立了 渲染樹
,以後瀏覽器就會在屏幕上繪製圖形。服務器
優化運行時的渲染和腳本執行當然相當重要,但對於運行在瀏覽器中的應用來講,迅速而有效的獲取網絡資源纔是第一要義websocket
那麼 HTTP 如何有效的獲取網絡資源?網絡
在 HTTP1.0 中,每一個 TCP 連接開始都有三次握手,要經歷一次客戶端與服務器間的完整往返。架構
而在支持持久鏈接的狀況下,就能夠避免第二次 TCP 鏈接時的三次握手、消除另外一次 TCP 滿啓動的往返,節約網絡請求。socket
HTTP1.1 默認啓用持久鏈接,能夠在 HTTP 首部添加:佈局
Connection: Keep-Alive
字段來明確要求服務器使用持久鏈接。
// TODO
持久鏈接對鏈接的性能提高巨大,但瀏覽器在一次請求發起後呆呆的等待服務器的相應卻也不是辦法。
而後大多數現代瀏覽器支持了主機打開6個鏈接,這意味着:
這樣感受瀏覽器能夠歡快的加載網絡資源了。可是這樣的代價、成本卻提升了,CPU 佔用率提升了,瀏覽器的開發成本也提升了。
整體來講,這仍是沒有從根本上解決 HTTP 的限制,是客戶端對於web性能提高的一個權宜之計。
爲何限制每一個主機最多6個鏈接,若是客戶端超過了最大的鏈接數,那麼後來的全部的客戶端請求都會被阻塞。好比,在一個主機上同時打開6個並行下載,再打開第七個請求時,這個請求會掛起,直到前面的請求完成纔會執行。這樣的狀況並非罕見,好比在應用中,
websocket
、Server sent event
和掛起xhr
,都會佔用一個 TCP 鏈接。
HTTP2.0 中新的二進制分幀層將 HTTP 消息分解爲互不依賴的幀,而後亂序發送,最後在另外一端從新組合起來。
有點懵,經過一幅圖來了解原理:
HTTP2.0 把消息分解爲獨立幀,交錯發送,而後在另外一端按照每一個包從新組裝(有木有像坐地鐵的感受),就實現了一個鏈接上有多個請求和響應,從而帶來了巨大的性能提高:
等等...
參考
Web 性能權威指南
HTTP/2 for a Faster Web