打開一個頁面的過程有很多優(yōu)化點,包括前端和客戶端,常規(guī)的前端和后端的性能優(yōu)化在桌面時代已經(jīng)有醉佳實踐,主要的是:
降低請求量:合并資源,減少 HTTP 請求數(shù),minify / gzip 壓縮,webP,lazyLoad。
加快請求速度:預解析DNS,減少域名數(shù),并行加載,CDN 分發(fā)。
緩存:HTTP 協(xié)議緩存請求,離線緩存 manifest,離線數(shù)據(jù)緩存localStorage。
渲染:JS/CSS優(yōu)化,加載順序,服務端渲染,pipeline。
其中對首屏啟動速度影響醉大的就是網(wǎng)絡請求,所以優(yōu)化的重點就是緩存,這里著重說一下前端對請求的緩存策略。我們再細分一下,分成 HTML 的緩存,JS/CSS/image 資源的緩存,以及 json 數(shù)據(jù)的緩存。
HTML 和 JS/CSS/image 資源都屬于靜態(tài)文件,HTTP 本身提供了緩存協(xié)議,瀏覽器實現(xiàn)了這些協(xié)議,可以做到靜態(tài)文件的緩存,具體可以參考這里,總的來說,就是兩種緩存:
詢問是否有更新:根據(jù) If-Modified-Since / ETag 等協(xié)議向后端請求詢問是否有更新,沒有更新返回304,瀏覽器使用本地緩存。
直接使用本地緩存:根據(jù)協(xié)議里的 Cache-Control / Expires 字段去確定多長時間內(nèi)可以不去發(fā)請求詢問更新,直接使用本地緩存。
前端能做的醉大限度的緩存策略是:HTML 文件每次都向服務器詢問是否有更新,JS/CSS/Image資源文件則不請求更新,直接使用本地緩存。那 JS/CSS 資源文件如何更新?常見做法是在在構建過程中給每個資源文件一個版本號或hash值,若資源文件有更新,版本號和 hash 值變化,這個資源請求的 URL 就變化了,同時對應的 HTML 頁面更新,變成請求新的資源URL,資源也就更新了。
json 數(shù)據(jù)的緩存可以用 localStorage 緩存請求下來的數(shù)據(jù),可以在受次顯示時先用本地數(shù)據(jù),再請求更新,這都由前端 JS 控制。
這些緩存策略可以實現(xiàn) JS/CSS 等資源文件以及用戶數(shù)據(jù)的緩存的全緩存,可以做到每次都直接使用本地緩存數(shù)據(jù),不用等待網(wǎng)絡請求。但 HTML 文件的緩存做不到,對于 HTML 文件,如果把 Expires / max-age 時間設長了,長時間只使用本地緩存,那更新就不及時,如果設短了,每次打開頁面都要發(fā)網(wǎng)絡請求詢問是否有更新,再確定是否使用本地資源,一般前端在這里的策略是每次都請求,這在弱網(wǎng)情況下用戶感受到的白屏時間仍然會很長。所以 HTML 文件的“緩存”和跟“更新”間存在矛盾。