![]()
一個單頁React應用,每秒都在崩潰邊緣試探,最終扛住了每月5000萬次訪問。這不是魔法,是三個被大多數團隊忽略的工程決策——而它們幾乎零成本。
第一刀:ISR不是優化,是生存策略
我加入時,Quran.com還在用客戶端渲染。每個用戶打開章節頁,都要等服務器現場拼HTML。中東和亞洲用戶平均等3秒,很多人直接關掉。
遷移到Next.js的增量靜態再生(ISR, Incremental Static Regeneration)后,我們在構建時預渲染全部章節頁,每小時后臺刷新一次。內容幾乎不變的古蘭經章節,變成了純靜態文件。
首字節時間(TTFB, Time to First Byte)在亞洲和中東下降超過70%。不是優化,是直接把用戶體驗從"加載中"拽進了"已呈現"。
但ISR有個陷阱:默認配置下,CDN不會乖乖配合。很多團隊到這里就停了,以為"用了Next.js就夠了"。
第二刀:CDN緩存的隱藏語法
我們在Vercel前加了Cloudflare,不是為了冗余,是為了劫持緩存邏輯。關鍵在這行配置:
Cache-Control: public, s-maxage=3600, stale-while-revalidate=86400
翻譯成人話:用戶永遠拿到緩存版本,哪怕它"過期"了——后臺悄悄去驗證更新,用戶無感知。利雅得、卡拉奇、雅加達的用戶,現在從最近的節點取頁面,而不是等美國服務器響應。
CDN緩存命中率從約40%飆升到92%。剩下8%才是真的需要回源的新請求。
這個stale-while-revalidate頭部,被無數Next.js教程跳過。它不是什么新特性,2017年就進了RFC,但 production 里見過的人不多。原因很諷刺:本地開發測不出來,必須上真流量才能看見效果。
第三刀:對依賴的"審計式"殘忍
5000萬用戶意味著任何1KB的浪費都會被放大。我們逐行審查node_modules,發現三個"體積刺客":一個圖表庫只用了10%的API,卻拖進全部D3;一個日期處理庫和原生Intl.DateTimeFormat功能重疊;還有個工具函數庫,我們自己重寫只需要200行。
配合激進的代碼分割(Code Splitting),把路由級組件拆成獨立chunk。
初始JS包體積縮減約45%。在2G網絡為主的南亞市場,這意味著"能打開"和"直接放棄"的區別。
有個細節:我們沒動業務代碼,全是基礎設施層的手術。很多團隊一上來就重寫組件,其實是抓錯了優先級。
被誤讀的"過早優化"
這三件事做完,團隊內部有過爭論。有人覺得"我們還沒到那個規模",ISR和邊緣緩存是"過早優化"。
我的回應很直接:等你有規模問題時,你已經沒空重構了。5000萬用戶下的100毫秒優化,每天影響數百萬次訪問。這不是性能競賽,是留存率的復利計算。
現在回頭看,那些"看起來太早"的決策,恰恰是后來不用凌晨救火的原因。
如果你在用Next.js做內容型產品,ISR和邊緣緩存不是可選項。構建時就埋進去,比事后拆彈便宜一百倍。
最后留個數據:遷移完成后,我們在巴基斯坦的用戶次日留存提升了多少?原文沒提,但作者說"更快加載意味著更多回訪"——這個因果鏈條,你的團隊敢押注嗎?
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.