嗨,送你一張Web性能優化地圖

Link: ; rel=preload; as=style

4.6 快速響應的用戶界面

PSI(Perceptual Speed Index,感知速度指數)是提升用戶體驗的重要指標,讓用戶感覺到頁面的反饋比沒有反饋體驗要好很多。

可以嘗試使用骨架屏或添加一些Loading過渡動畫提示用戶體驗。

輸入響應(Input responsiveness)指標同樣重要,甚至更重要。試想,用戶點擊了網頁後缺毫無反應會是什麼心情。JS的單線程大家已經不能再熟悉,這意味著當JS在運行時用戶界面處於“鎖定”狀態,所以JS同步執行的時間越長,用戶等待響應的時間也就越長。

據調查,JS執行100毫秒以上用戶就會明顯覺得網頁變卡了。所以要嚴格限制每個JS任務執行時間不能超過100毫秒。

解決方案是可以將一個大任務拆分成多個小任務分佈在不同的Macrotask中執行(通俗的說是將大的JS任務拆分成多個小任務異步執行)。或者使用WebWorkers,它可以在UI線程外執行JS代碼運算,不會阻塞UI線程,所以不會影響用戶體驗。

應用越複雜,主動管理UI線程就越重要

5. 構建優化

現代前端應用都需要有構建的過程,項目在構建過程中是否進行了合理的優化,會對Web應用的性能有著巨大的影響。例如:影響構建後文件的體積、代碼執行效率、文件加載時間、首次有效繪製指標等。

5.1 使用預編譯

拿Vue舉例,如果您使用單文件組件開發項目,組件會在編譯階段將模板編譯為渲染函數。最終代碼被執行時可以直接執行渲染函數進行渲染。而如果您沒有使用單文件組件預編譯代碼,而是在網頁中引入vue.min.js,那麼應用在運行時需要先將模板編譯成渲染函數,然後再執行渲染函數進行渲染。相比預編譯,多了模板編譯的步驟,所以會浪費很多性能。

5.2 使用 Tree-shaking、Scope hoisting、Code-splitting

Tree-shaking是一種在構建過程中清除無用代碼的技術。使用Tree-shaking可以減少構建後文件的體積。

目前Webpack與Rollup都支持Scope Hoisting。它們可以檢查import鏈,並儘可能的將散亂的模塊放到一個函數中,前提是不能造成代碼冗餘。所以只有被引用了一次的模塊才會被合併。使用Scope Hoisting可以讓代碼體積更小並且可以降低代碼在運行時的內存開銷,同時它的運行速度更快。前面2.1節介紹了變量從局部作用域到全局作用域的搜索過程越長執行速度越慢,Scope Hoisting可以減少搜索時間。

code-splitting是Webpack中最引人注目的特性之一。此特性能夠把代碼分離到不同的bundle中,然後可以按需加載或並行加載這些文件。code-splitting可以用於獲取更小的bundle,以及控制資源加載優先級,如果使用合理,會極大影響加載時間。

5.3 服務端渲染(SSR)

單頁應用需要等JS加載完畢後在前端渲染頁面,也就是說在JS加載完畢並開始執行渲染操作前的這段時間裡瀏覽器會產生白屏。

服務端渲染(Server Side Render,簡稱SSR)的意義在於彌補主要內容在前端渲染的成本,減少白屏時間,提升首次有效繪製的速度。可以使用服務端渲染來獲得更快的首次有效繪製。

比較推薦的做法是:使用服務端渲染靜態HTML來獲得更快的首次有效繪製,一旦JavaScript加載完畢再將頁面接管下來。

5.4 使用import函數動態導入模塊

使用import函數可以在運行時動態地加載ES2015模塊,從而實現按需加載的需求。

這種優化在單頁應用中變得尤為重要,在切換路由的時候動態導入當前路由所需的模塊,會避免加載冗餘的模塊(試想如果在首次加載頁面時一次性把整個站點所需要的所有模塊都同時加載下來會加載多少非必須的JS,應該儘可能的讓加載的JS更小,只在首屏加載需要的JS)。

使用靜態import導入初始依賴模塊。其他情況下使用動態import按需加載依賴

5.5 使用HTTP緩存頭

正確設置expires,cache-control和其他HTTP緩存頭。

推薦使用Cache-control: immutable避免重新驗證。

6. 其他

其他一些值得考慮的優化點:

  • HTTP2使用最高級的CDN(付費的比免費的強的多)優化字體其他垂直領域的性能優化

7. 性能監控

最後,你可能需要一個性能檢測工具來持續監視網站的性能。

8. 總結

最後用一張圖來總結這篇文章所表達的內容,感謝@anjia幫忙畫的這張圖。

嗨,送你一張Web性能優化地圖


分享到:


相關文章: