關(guān)于前端性能優(yōu)化的困惑
前端性能優(yōu)化是前度面試??嫉膯?wèn)題,答案說(shuō)來(lái)復(fù)雜,其實(shí)總結(jié)下來(lái)就是:減少或拆分資源 + 異步加載 現(xiàn)在都搞成八股文了,面試之前背誦一下。
還有緩存。
但純前端的緩存其實(shí)作用不大,使用場(chǎng)景也不多,例如 Vue computed keep-alive,React useMemo 在絕大部分場(chǎng)景下都用不到。雖然面試的時(shí)候我們得說(shuō)出來(lái)。
HTTP 緩存是網(wǎng)絡(luò)層面的,操作系統(tǒng)和瀏覽器實(shí)現(xiàn)的,并不是前端實(shí)現(xiàn)的。雖然作為前端工程師要掌握這些知識(shí),但大多數(shù)情況下并不需要自己親自去配置。
實(shí)際工作中,其實(shí)絕大部分前端項(xiàng)目,代碼量都沒(méi)有非常大,不拆分代碼,不異步加載也不會(huì)有太大的影響。
我這兩年 1v1 評(píng)審過(guò)很多前端簡(jiǎn)歷,大家都會(huì)有這樣一個(gè)困惑:?jiǎn)柕角岸诵阅軆?yōu)化,感覺(jué)工作幾年了,也沒(méi)做什么優(yōu)化,而且也想不出前端能做什么優(yōu)化。
其實(shí)這是正常的,絕大部分前端項(xiàng)目、前端工作都不需要優(yōu)化,而且從全棧角度看,前端能做的優(yōu)化也很有限。
但面試是是面試,工作是工作。面試造火箭,工作擰螺絲,這個(gè)大家都知道,不要為此較真。
從全棧角度的性能優(yōu)化
從我開(kāi)發(fā) 劃水AI 全棧項(xiàng)目的經(jīng)歷來(lái)看,一個(gè) web 系統(tǒng)影響性能的諸多因素,按優(yōu)先級(jí)排序:
第一是網(wǎng)絡(luò)情況,服務(wù)器地理位置和客戶端的距離,大型 web 系統(tǒng)在全國(guó)、全球各個(gè)節(jié)點(diǎn)都會(huì)部署服務(wù)器,還有 CDN DCDN EDGE 邊緣計(jì)算等服務(wù),都是解決這個(gè)問(wèn)題。
第二是服務(wù)端的延遲,最主要的是 I/O 延遲,例如查詢數(shù)據(jù)庫(kù)、第三方服務(wù)等。
第三是 SSR 服務(wù)端渲染,一次性返回內(nèi)容,盡量減少網(wǎng)絡(luò)情況。
第四才是純前端性能優(yōu)化,使用 loading 提示、異步加載等。其實(shí)到了純前端應(yīng)該更多是體驗(yàn)優(yōu)化,而不是性能優(yōu)化。
網(wǎng)絡(luò)
網(wǎng)絡(luò)是最重要的一個(gè)因素,也是我們最不易察覺(jué)的因素,尤其初學(xué)者,甚至都沒(méi)有獨(dú)立發(fā)布上線過(guò)項(xiàng)目。
劃水AI 之前部署在海外服務(wù)器,使用 Sentry 性能監(jiān)控,TTFB 都超過(guò) 2s, FCP 接近 3s ,性能非常糟糕。
原因也很明顯,代碼無(wú)論如何優(yōu)化,TTFB 時(shí)間慢是繞不過(guò)去的,這是網(wǎng)絡(luò)層面的。
還有,之前 CDN 也是部署在香港的,使用站長(zhǎng)工具做測(cè)試,會(huì)發(fā)現(xiàn)國(guó)內(nèi)訪問(wèn)速度非常慢。
文檔的多人協(xié)同編輯,之前總是不穩(wěn)定重新連接。我之前一直以為是代碼哪里寫錯(cuò)了,一直沒(méi)找到原因,后來(lái)發(fā)現(xiàn)是網(wǎng)絡(luò)不穩(wěn)定的問(wèn)題。因?yàn)閰f(xié)同編輯服務(wù)當(dāng)時(shí)是部署在亞馬遜 AWS 新加坡的服務(wù)器。
這兩天我剛剛把 劃水AI 服務(wù)遷移到國(guó)內(nèi),訪問(wèn)速度從感知上就不一樣了,又快又穩(wěn)定。具體的數(shù)據(jù)我還在跟蹤中,需要持續(xù)跟蹤幾天,過(guò)幾天統(tǒng)計(jì)出來(lái)再分享。
服務(wù)端響應(yīng)速度
首先是數(shù)據(jù)庫(kù)查詢速度,這是最常見(jiàn)的瓶頸。后端程序員都要熟練各種數(shù)據(jù)庫(kù)的優(yōu)化手段,前端不一定熟練,但要知道有這么回事。
現(xiàn)在 劃水AI 數(shù)據(jù)庫(kù)用的是 Supabase 服務(wù),是海外服務(wù)器。國(guó)內(nèi)目前還沒(méi)有類似的可替代服務(wù),所以暫時(shí)還不能遷移。
所以每次切換文檔,都會(huì)有 1s 左右的 loading 時(shí)間,體驗(yàn)上也說(shuō)的過(guò)去。比用之前的 AWS 新加坡服務(wù)器要快了很多。
其次是第三方服務(wù)的速度,例如 AI 服務(wù)的接口響應(yīng)速度,有時(shí)候會(huì)比較慢,需要等待 3s 以上。
但 deepseek 網(wǎng)頁(yè)版也挺慢的,也得 loading 2-3s 時(shí)間。ChatGPT 倒是挺快,但我們得用中轉(zhuǎn)服務(wù),這一中轉(zhuǎn)又慢了。
還有例如登錄時(shí) GitHub 驗(yàn)證、發(fā)送郵件驗(yàn)證等,這個(gè)目前也不快,接下來(lái)我會(huì)考慮改用短信驗(yàn)證碼的方式來(lái)登錄。
第三方服務(wù)的問(wèn)題是最無(wú)解的。
SSR 服務(wù)端渲染
服務(wù)端獲取數(shù)據(jù),直接給出結(jié)果,或者判斷跳轉(zhuǎn)頁(yè)面(返回 302),而不是前端 ajax 獲取數(shù)據(jù)再做判斷。
后者再如何優(yōu)化,也會(huì)比前者多一步網(wǎng)絡(luò)請(qǐng)求,50-100ms 是少不了的。前端壓縮、拆分多少資源也填不上這個(gè)坑。
純前端性能優(yōu)化
面試中常說(shuō)的性能優(yōu)化方式,如 JS 代碼拆分、異步組件、路由懶加載等,可能減少的就是幾十 KB 的數(shù)據(jù)量,而這幾十 KB 在現(xiàn)代網(wǎng)絡(luò)速度和 CDN 幾乎感知不出來(lái)。
而且還有 HTTP 緩存,可能第一次訪問(wèn)時(shí)候可能慢一點(diǎn)點(diǎn),再次訪問(wèn)時(shí)靜態(tài)資源使用緩存,就不會(huì)再影響速度。
最后還有壓縮,網(wǎng)絡(luò)請(qǐng)求通常采用 GZIP 壓縮,可把資源體積壓縮到 1/3 大小。例如,你把 JS 減少了 100kb,看似優(yōu)化了很多,但實(shí)際在網(wǎng)絡(luò)傳輸?shù)臅r(shí)候壓縮完只有 30kb ,還不如一個(gè)圖片體積大。
而有時(shí)候?yàn)榱诉@些優(yōu)化反而把 webpack 或 vite 配置的亂七八糟的,反而增加了代碼復(fù)雜度,容易出問(wèn)題。
但前端可以做很多體驗(yàn)優(yōu)化的事情,例如使用 loading 效果和圖片懶加載,雖然速度還一樣,但用戶體驗(yàn)會(huì)更好,使用更流暢。這也是有很大產(chǎn)品價(jià)值的。
最后
一個(gè) web 系統(tǒng)的性能瓶頸很少會(huì)出現(xiàn)在前端,前端資源的速度問(wèn)題在網(wǎng)絡(luò)層面很好解決。所以希望每一位前端開(kāi)發(fā)都要有全棧思維,能站在全棧的角度去思考問(wèn)題和解決問(wèn)題。