Web頁面全鏈路性能優(yōu)化指南

性能優(yōu)化不單指優(yōu)化一個頁面的打開速度,在開發(fā)環(huán)境將一個項目的啟動時間縮短使開發(fā)體驗更好也屬于性能優(yōu)化,大文件上傳時為其添加分片上傳、斷點續(xù)傳也屬于性能優(yōu)化。在項目開發(fā)以及用戶使用的過程中,能夠讓任何一個鏈路快一點,都可以被叫做性能優(yōu)化。
本文會對web頁面的全鏈路進行完整的講解并針對每一步找到能做的性能優(yōu)化點,本文的目標是極致的性能優(yōu)化。
因為針對性能優(yōu)化,能做的點會特別特別的多,覆蓋著整個互聯(lián)網(wǎng)的訪問流程,因此此文章的內(nèi)容會比較多且雜,筆者會盡量對內(nèi)容進行分類講解。
本文的大致流程為先講理論知識,比如如何評價一個頁面的性能好與不好、如果獲取性能指標,如何使用各種性能相關工具,瀏覽器如何獲取并渲染頁面。筆者認為這些都是基礎,只有了解了這些基礎才能開始考慮如何去優(yōu)化。
接下來我們會進入性能優(yōu)化環(huán)節(jié),在這個環(huán)節(jié)我會詳細講解在頁面的整個流程中,哪些地方可以做哪些優(yōu)化。
目錄
進程與線程
輸入url到頁面展示完整過程
1.用戶輸入
2.卸載原頁面并重定向到新頁面
3.處理Service Worker
4.網(wǎng)絡請求
5.服務端響應
6.瀏覽器渲染詳細流程
瀏覽器處理每一幀的流程
Chrome Performance(性能)
Chrome Performance 工具的使用
Performance API介紹
使用Performance API獲取性能相關指標
Coverage(覆蓋率)
Lighthouse
Network(網(wǎng)絡)
網(wǎng)絡請求中的Timing(時間)
網(wǎng)絡請求的優(yōu)先級
網(wǎng)頁總資源信息
Network配置
網(wǎng)絡優(yōu)化策略
減少HTTP請求數(shù)
使用HTTP緩存
使用 HTTP/2.0
避免重定向
使用 dns-prefetch
使用域名分片
CDN
壓縮
使用contenthash
合理使用preload、prefetch
瀏覽器渲染優(yōu)化策略
關鍵渲染路徑
強制同步布局問題
如何減少重排與重繪
靜態(tài)文件優(yōu)化策略
圖片格式
圖片優(yōu)化
HTML優(yōu)化
CSS優(yōu)化
JS優(yōu)化
字體優(yōu)化
瀏覽器儲存優(yōu)化策略
Cookie
LocalStorage
SessionStorage
IndexDB
其他優(yōu)化策略
使用PWA提高用戶體驗
瀏覽器渲染原理
我們需要知道瀏覽器是如何渲染一個頁面的,我們才能知道如何對頁面進行性能優(yōu)化,所以這里我們對一些基礎知識進行講解
進程與線程
瀏覽器有多種進程,其中最主要的5種進程如下

瀏覽器進程 負責界面展示、用戶交互、子進程管理、提供存儲等 渲染進程 每個頁面都有一個單獨的渲染進程,用于渲染頁面,包含webworker線程 網(wǎng)絡進程 主要處理網(wǎng)絡資源加載(HTML、CSS、JS、IMAGE、AJAX等) GPU進程 3D繪制,提高性能 插件進程 chrome插件,每個插件占用一個進程
輸入url到頁面展示完整過程
圖1

1.用戶輸入
用戶在瀏覽器進程輸入并按下回車健后,瀏覽器判斷用戶輸入的url是否為正確的url,如果不是,則使用默認的搜索引擎將該關鍵字拼接成url。
2.卸載原頁面并重定向到新頁面
然后瀏覽器會將現(xiàn)有頁面卸載掉并重定向到用戶新輸入的url頁面,也就是圖中【Process Unload Event】和【Redirect】流程。
此時瀏覽器會準備一個渲染進程用于渲染即將到來的頁面,和一個網(wǎng)絡進程用于發(fā)送網(wǎng)絡請求。
3.處理Service Worker
如果當前頁面注冊了Service Worker那么它可以攔截當前網(wǎng)站所有的請求,進行判斷是否需要向遠程發(fā)送網(wǎng)絡請求。也就是圖中【Service Worker Init】與【Service Worker Fecth Event 】步驟
如果不需要發(fā)送網(wǎng)絡請求,則取本地文件。如果需要則進行下一步。
4.網(wǎng)絡請求
OSI網(wǎng)絡七層模型:物理層、數(shù)據(jù)鏈路層、網(wǎng)絡層、傳輸層、會話層、表示層、應用層
在實際應用中物理層、數(shù)據(jù)鏈路層被統(tǒng)稱為物理層,會話層、表示層、應用層被統(tǒng)稱為應用層,所以實際使用時通常分為4個層級
【物理層】>【網(wǎng)絡層(IP)】>【傳輸層(TCP/UDP)】>【應用層(HTTP)】
也就是圖中【HTTP Cache】、【DNS】、【TCP】、【Request】、【Response】步驟
圖2

瀏覽器會拿著url通過網(wǎng)絡進程進行如下步驟
根據(jù)url查詢本地是否已經(jīng)有強制緩存,如果有則判斷緩存是否過期,如果沒過期則直接返回緩存內(nèi)容,也就是圖1中【HTTP Cache】步驟
如果沒有強制緩存或者緩存已過期,則將該請求加入隊列進行排隊準備發(fā)送網(wǎng)絡請求,也就是圖2中【正在排隊】,然后進入DNS解析階段,也就是圖1中【DNS】以及圖2中的【DNS查找】,DNS根據(jù)域名解析出對應的IP地址。(DNS基于UDP)。
然后使用IP尋址找到對方,然后根據(jù)IP地址+端口號創(chuàng)建一個TCP連接(三次握手),也就是圖1中【TCP】以及圖2中的【初始連接】創(chuàng)建完成后利用TCP連接來傳輸數(shù)據(jù)。(TCP會將數(shù)據(jù)拆分為多個數(shù)據(jù)包,進行有序傳輸,如果丟包會重發(fā),TCP的特點是可靠、有序)
判斷當前協(xié)議是否為https,如果為https,則進行SSL協(xié)商,將數(shù)據(jù)進行加密,如果為http協(xié)議則不進行加密(明文傳輸),也就是圖2中的【SSL】。
開始發(fā)送http請求(請求行/請求頭/請求體),也就是圖1中【Request】以及圖2中的【已發(fā)送請求】。HTTP協(xié)議有多個版本,目前使用最多的版本為HTTP/1.1,HTTP/1.1發(fā)送完成后默認不會斷開。keep-alive 默認打開,為了下次傳輸數(shù)據(jù)時復用上次創(chuàng)建的連接。每個域名最多同時建立6個TCP連接,所以同一時間最多發(fā)生6個請求。
HTTP協(xié)議的各個版本特性如下:
HTTP/0.9沒有請求頭和響應頭,不區(qū)分傳輸?shù)膬?nèi)容類型,因為當時只傳輸HTML。HTTP/1.0提供了請求頭和響應頭,可以傳輸不同類型的內(nèi)容數(shù)據(jù)。根據(jù)請求響應頭的不同來處理不同的資源,HTTP1.0每次發(fā)完請求都會斷開TCP連接。有新的請求時再次創(chuàng)建TCP連接。HTTP/1.1默認開啟了 keep-alive ,它能夠讓一個TCP連接中傳輸多個HTTP請求,也叫鏈路復用。但一個TCP連接同一時間只能發(fā)送一個HTTP請求,為了不阻塞多個請求,Chrome允許創(chuàng)建6個TCP連接,所以在HTTP/1.1中,最多能夠同時發(fā)送6個網(wǎng)絡請求。HTTP/2.0HTTP/2.0使用同一個TCP連接來發(fā)送數(shù)據(jù),他把多個請求通過二進制分貞層實現(xiàn)了分貞,然后把數(shù)據(jù)傳輸給服務器。也叫多路復用,多個請求復用同一個TCP連接。HTTP/2.0會將所有以:開頭的請求頭做一個映射表,然后使用hpack進行壓縮,使用這種方式會使請求頭更小。服務器可主動推送數(shù)據(jù)給客戶端。HTTP/3.0使用UDP實現(xiàn),在UDP上一層加入一層QUIC協(xié)議,解決了TCP協(xié)議中的隊頭阻塞問題。服務器收到數(shù)據(jù)后解析HTTP請求(請求行/請求頭/請求體),處理完成后生成狀態(tài)碼和HTTP響應(響應行/響應頭/響應體)后返回給客戶端,也就是圖2的【等待中】在做的事情。
客戶端接收到HTTP響應后根據(jù)狀態(tài)碼進行對應的處理,如果狀態(tài)碼為304則直接代表協(xié)商緩存生效,直接取本地的緩存文件。如果不是則下載內(nèi)容。也就是圖1中【Response】以及圖2中的【下載內(nèi)容】步驟。
5.服務端響應
在4.網(wǎng)絡請求第6步中,服務器收到HTTP請求后需要根據(jù)請求信息來進行解析,并返回給客戶端想要的數(shù)據(jù),這也就服務端響應。
服務端可以響應并返回給客戶端很多種類型的資源,這里主要介紹html類型
目前前端處理服務端響應html請求主要分為SSR服務端渲染與CSR客戶端渲染,CSR就是返回一個空的HTML模版,然后瀏覽器加載js后通過js動態(tài)渲染頁面。SSR是服務端在接受到請求時事先在服務端渲染好html返回給客戶端后,客戶端再進行客戶端激活。
在打開一個站點的首屏頁的完整鏈路中,使用SSR服務端渲染時的速度要遠大于CSR客戶端渲染,并且SSR對SEO友好。所以對于首屏加載速度比較敏感或者需要優(yōu)化SEO的站點來說,使用SSR是更好的選擇。
6.瀏覽器渲染詳細流程
瀏覽器渲染詳細流程主要在4.網(wǎng)絡請求中的地7步。瀏覽器下載完html內(nèi)容后進行解析何渲染頁面的流程。

渲染流程分為4種情況,
HTML中無任何CSS相關標簽 CSS相關標簽在HTML最頂部,且在解析到內(nèi)容標簽( )時已經(jīng)解析完CSS相關標簽CSS相關標簽在HTML最頂部,但在解析到內(nèi)容標簽( )時CSS相關標簽尚未解析完CSS相關標簽在HTML最底部
下面的流程是對上圖的文字版解析。讀者可將以上4種情況分別帶入到如下的渲染流程中走一遍。就能理解瀏覽器的完整渲染過程了。
【HTML】
瀏覽器收到html資源后先預掃描和
