Vercel React 最佳實踐 是做什麼的?
由 Vercel 維護的 React 與 Next.js 應用程式全面效能優化指南。包含 70 條規則,橫跨 8 個類別,按影響程度優先排序,以引導自動重構與程式碼生成。
何時套用
請參考以下準則:
- 撰寫新的 React 元件或 Next.js 頁面時
- 實作資料擷取(客戶端或伺服器端)時
- 審查程式碼的效能問題時
- 重構現有的 React/Next.js 程式碼時
- 最佳化套件大小或載入時間時
依優先順序排列的規則類別
| 優先序 | 類別 | 影響程度 | 前綴 |
|---|---|---|---|
| 1 | 消除瀑布效應 | 關鍵 | async- |
| 2 | 套件大小最佳化 | 關鍵 | bundle- |
| 3 | 伺服器端效能 | 高 | server- |
| 4 | 客戶端資料擷取 | 中高 | client- |
| 5 | 重新渲染最佳化 | 中 | rerender- |
| 6 | 渲染效能 | 中 | rendering- |
| 7 | JavaScript 效能 | 低中 | js- |
| 8 | 進階模式 | 低 | advanced- |
快速參考
1. 消除瀑布效應 (關鍵)
async-cheap-condition-before-await- 在等待旗標或遠端值之前,先檢查便宜的同步條件async-defer-await- 將 await 移到實際使用的分支中async-parallel- 對獨立操作使用 Promise.all()async-dependencies- 對部分相依性使用 better-allasync-api-routes- 在 API 路由中儘早啟動 Promise,延後 awaitasync-suspense-boundaries- 使用 Suspense 串流內容
2. 套件大小最佳化 (關鍵)
bundle-barrel-imports- 直接匯入,避免 barrel 檔案bundle-analyzable-paths- 偏好靜態可分析的匯入與檔案系統路徑,以避免寬鬆的套件與追蹤bundle-dynamic-imports- 對重量級元件使用 next/dynamicbundle-defer-third-party- 在 hydration 之後載入分析/記錄bundle-conditional- 僅在功能啟用時載入模組bundle-preload- 在滑鼠懸停/聚焦時預載,提升感知速度
3. 伺服器端效能 (高)
server-auth-actions- 像驗證 API 路由一樣驗證伺服器動作server-cache-react- 使用 React.cache() 進行每個請求的去重server-cache-lru- 使用 LRU 快取進行跨請求快取server-dedup-props- 避免在 RSC props 中重複序列化server-hoist-static-io- 將靜態 I/O (字型、標誌) 提升至模組層級server-no-shared-module-state- 避免在 RSC/SSR 中使用模組層級的可變請求狀態server-serialization- 最小化傳遞給客戶端元件的資料server-parallel-fetching- 重構元件以並行化擷取server-parallel-nested-fetching- 在 Promise.all 中為每個項目鏈結巢狀擷取server-after-nonblocking- 使用 after() 處理非阻塞操作
4. 客戶端資料擷取 (中高)
client-swr-dedup- 使用 SWR 進行自動請求去重client-event-listeners- 去重全域事件監聽器client-passive-event-listeners- 對滾動使用 passive 監聽器client-localstorage-schema- 版本化並最小化 localStorage 資料
5. 重新渲染最佳化 (中)
rerender-defer-reads- 不要訂閱僅在回呼中使用的狀態rerender-memo- 將昂貴的工作提取到已 memoized 的元件中rerender-memo-with-default-value- 提升預設的非基本型別 propsrerender-dependencies- 在 effect 中使用基本型別依賴rerender-derived-state- 訂閱衍生的布林值,而非原始值rerender-derived-state-no-effect- 在渲染期間衍生狀態,而非 effectrerender-functional-setstate- 使用 functional setState 獲取穩定的回呼rerender-lazy-state-init- 對昂貴的初始值傳遞函式給 useStatererender-simple-expression-in-memo- 避免對簡單基本型別使用 memorerender-split-combined-hooks- 拆分具有獨立依賴的 hooksrerender-move-effect-to-event- 將互動邏輯放入事件處理常式中rerender-transitions- 對非緊急更新使用 startTransitionrerender-use-deferred-value- 延遲昂貴的渲染,保持輸入響應rerender-use-ref-transient-values- 對瞬態頻繁值使用 refsrerender-no-inline-components- 不要在元件內部定義元件
6. 渲染效能 (中)
rendering-animate-svg-wrapper- 動畫化 div 包裝器,而非 SVG 元素rendering-content-visibility- 對長列表使用 content-visibilityrendering-hoist-jsx- 將靜態 JSX 提取到元件外部rendering-svg-precision- 降低 SVG 座標精度rendering-hydration-no-flicker- 對僅客戶端資料使用 inline scriptrendering-hydration-suppress-warning- 抑制預期的不匹配rendering-activity- 使用 Activity 元件來顯示/隱藏rendering-conditional-render- 使用三元運算子,而非 && 進行條件渲染rendering-usetransition-loading- 偏好使用 useTransition 處理載入狀態rendering-resource-hints- 使用 React DOM 資源提示進行預載rendering-script-defer-async- 對 script 標籤使用 defer 或 async
7. JavaScript 效能 (低中)
js-batch-dom-css- 透過類別或 cssText 分組 CSS 變更js-index-maps- 對重複查詢建立 Mapjs-cache-property-access- 在迴圈中快取物件屬性js-cache-function-results- 在模組層級的 Map 中快取函式結果js-cache-storage- 快取 localStorage/sessionStorage 讀取js-combine-iterations- 將多個 filter/map 合併為一個迴圈js-length-check-first- 在進行昂貴的比較之前,先檢查陣列長度js-early-exit- 從函式中提前返回js-hoist-regexp- 將 RegExp 建立提升到迴圈外部js-min-max-loop- 使用迴圈尋找最小/最大值,而非排序js-set-map-lookups- 使用 Set/Map 進行 O(1) 查詢js-tosorted-immutable- 使用 toSorted() 以保持不變性js-flatmap-filter- 使用 flatMap 在一次遍歷中進行映射與過濾js-request-idle-callback- 將非關鍵工作延遲到瀏覽器空閒時間
8. 進階模式 (低)
advanced-effect-event-deps- 不要將useEffectEvent的結果放在 effect 依賴中advanced-event-handler-refs- 將事件處理常式儲存在 refs 中advanced-init-once- 每次應用程式載入時初始化一次advanced-use-latest- 使用 useLatest 獲取穩定的回呼 refs
如何使用
閱讀個別規則檔案以獲取詳細說明和程式碼範例:
rules/async-parallel.md
rules/bundle-barrel-imports.md
每個規則檔案包含:
- 為何重要的簡短說明
- 帶有說明的錯誤程式碼範例
- 帶有說明的正確程式碼範例
- 其他背景資訊與參考資料
完整彙編文件
如需包含所有規則展開的完整指南:AGENTS.md