Web 性能指標
web 性能優化到底在優化什麼?
你可能會說優化的是用戶體驗,但用戶體驗是不可測量的,我們必須把用戶體驗變成可測量的指標,這些指標包括:
- 用戶按下回車
- 由內容出現時(一般3秒之內還沒有內容出現,用戶就會比較焦慮,會關掉頁面)
- DOM ready 事件發生(dom content loading ,代表 HTML 內容全部解析完,js 也基本執行完了,但並不保證圖片已經全部加載和 css 樣式加載完,就是 network 裏面那跟藍色的線)
- 頁面可交互(JS 都執行了,並且把事件都綁定了,用戶點擊按鈕不會出現沒反應的情況)
- onLoad 事件發生
- 動態資源加載完畢
DNS prefetch
DNS 預解析
假設 index.html 的部分代碼爲:
<script src="http://a.com/1.js"></script>
<script src="http://b.com/1.js"></script>
那麼過程就是首先對 a.com 進行 dns 查詢 => 拿到 ip 地址以後 => 下載a.js => 對 b.com 進行 dns 查詢(一定會等 a.js 下載執行完畢後纔開始) => 拿到 ip 地址以後 => 下載b.js
如果 a.com 和 b.com 同時先進行 dns 預解析,那麼就能節省一定的時間
優化(兩種方法)
前端
<link ref="des-prefetch" href="https://a.com/" >
<link ref="des-prefetch" href="https://b.com/" >
後端
// index.html 的響應頭裏寫
Link: <http://a.com />; rel=dns=prefetch
TCP 連接複用
正常流程:開啓 TCP => 請求 => 響應 => 關閉 => 開啓 TCP....
可以發現一直在重複開啓關閉,爲何不復用呢,開啓後就不關閉了,節約多次重複開啓關閉的時間。
實現
// 請求頭
Connection: keep-alive
// 響應頭
Connection: keep-alive
但是如果服務器一直開着將會非常佔用資源,用戶一多,服務器就頂不住了,所以一般都會在設置一個超時時間,如果超過多少秒還沒有再次發起連接,那麼將會強制關閉。
// 請求頭
KeepAlive: timeout=5, max=10
// 響應頭
KeepAlive: timeout=10, max=100
客戶端和服務器都可以設置這個字段,兩者可以不一樣,timeout 表示多少秒,max 表示多少次,一般來說聰明的瀏覽器會以服務器爲準(尊重服務器的能力),而傻一點的瀏覽器(如:IE)就堅持自己爲準
前端怎麼加 keep-alive?
如果用的 http/1.1 以上,會自動加。
也就是基本上不用去優化了。
並行化連接
因爲連接複用是串行的,當同時處理多個請求的時候還是太慢,所以需要並行連接。
也就是說同時建立好幾個請求(一般瀏覽器會設置最大數量,同一個域名一般 4-12 個)
那麼連接複用就沒有用了嗎?
答案是不會,因爲瀏覽器設置了連接上限,如果超出的連接數,那麼剩下的就會等待上一個請求結束後再進行復用。
🌰:
相同的 id 代表連接複用
HTTP 管道化
瀏覽器默認關閉,可能會有 BUG
🌰:
|一個 http 管道-------------------------
|| 1.css ----- 響應
| | 2.css ----- 響應
| | 3.css ----- 響應
|--------------------------------------
當在管道中發起(接近同時)三個請求時,會有如下問題:
- 瀏覽器必須要按照相當的順序返回響應,否則會對應不上,不像並行一樣,每次都是新的連接一一對應。
- 如果 1.css 因爲網絡波動特別慢,那麼 剩下的必須得等 1.css 響應結束纔可以繼續,因爲一旦 2.css 提前響應了就會被瀏覽器錯誤的當成 1.css 的響應。
所以他會導致請求之前的順序依賴,導致這樣的並行沒法導致最快的速度,所以一開始的 http 設計並不能滿足現在的需求,所以需要升級爲 HTTP/2.0