Vercel React ベストプラクティス
React および Next.js アプリケーション向けの包括的なパフォーマンス最適化ガイド。Vercel 管理。優先度順に並べられた 8 カテゴリ、70 ルールを含み、自動リファクタリングとコード生成を導きます。
適用タイミング
以下の場合に本ガイドラインを参照してください:
- 新しい 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-allを使うasync-api-routes- API ルートでは Promise を早く開始し、遅く await するasync-suspense-boundaries- Suspense を使ってコンテンツをストリーミングする
2. バンドルサイズ最適化(重大)
bundle-barrel-imports- 直接インポートし、バレルファイルを避けるbundle-analyzable-paths- 静的に解析可能なインポートパスとファイルシステムパスを優先し、広範囲なバンドルやトレースを避けるbundle-dynamic-imports- 重いコンポーネントにはnext/dynamicを使うbundle-defer-third-party- アナリティクス/ロギングはハイドレーション後に読み込む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- スクロールにはパッシブリスナーを使うclient-localstorage-schema- localStorage データのバージョン管理と最小化
5. 再レンダリング最適化(中)
rerender-defer-reads- コールバックでのみ使用する状態を購読しないrerender-memo- 重い処理をメモ化されたコンポーネントに抽出するrerender-memo-with-default-value- デフォルトの非プリミティブな props をホイストするrerender-dependencies- エフェクトではプリミティブな依存関係を使うrerender-derived-state- 生の値ではなく、派生した真偽値を購読するrerender-derived-state-no-effect- エフェクトではなくレンダリング中に状態を派生させるrerender-functional-setstate- 安定したコールバックのために関数型 setState を使うrerender-lazy-state-init- 高コストな値には関数を useState に渡すrerender-simple-expression-in-memo- 単純なプリミティブには memo を避けるrerender-split-combined-hooks- 独立した依存関係を持つフックを分割するrerender-move-effect-to-event- インタラクションロジックをイベントハンドラーに移動するrerender-transitions- 緊急でない更新にはstartTransitionを使うrerender-use-deferred-value- 高コストなレンダリングを遅延させて入力をレスポンシブに保つrerender-use-ref-transient-values- 一時的な頻繁な値には refs を使うrerender-no-inline-components- コンポーネント内でコンポーネントを定義しない
6. レンダリングパフォーマンス(中)
rendering-animate-svg-wrapper- SVG 要素ではなく div ラッパーをアニメーションするrendering-content-visibility- 長いリストにはcontent-visibilityを使うrendering-hoist-jsx- 静的な JSX をコンポーネントの外に引き上げるrendering-svg-precision- SVG 座標の精度を下げるrendering-hydration-no-flicker- クライアント専用データにはインラインスクリプトを使うrendering-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- 繰り返しのルックアップには Map を構築するjs-cache-property-access- ループ内でオブジェクトのプロパティをキャッシュするjs-cache-function-results- 関数の結果をモジュールレベルの Map にキャッシュするjs-cache-storage- localStorage/sessionStorage の読み取りをキャッシュするjs-combine-iterations- 複数の filter/map を 1 つのループに結合するjs-length-check-first- 高コストな比較の前に配列の長さをチェックするjs-early-exit- 関数から早期に return するjs-hoist-regexp- RegExp の生成をループの外に引き上げるjs-min-max-loop- 最小/最大を求めるには sort ではなくループを使うjs-set-map-lookups- Set/Map を使って O(1) のルックアップを実現するjs-tosorted-immutable- 不変性のためにtoSorted()を使うjs-flatmap-filter- flatMap を使ってマッピングとフィルタリングを 1 パスで行うjs-request-idle-callback- 重要でない処理をブラウザのアイドル時間に遅延させる
8. 高度なパターン(低)
advanced-effect-event-deps-useEffectEventの結果をエフェクトの依存関係に含めないadvanced-event-handler-refs- イベントハンドラーを refs に格納するadvanced-init-once- アプリの読み込みごとに 1 回だけ初期化するadvanced-use-latest- 安定したコールバック refs のためにuseLatestを使う
使い方
詳細な説明とコード例については個別のルールファイルを参照してください:
rules/async-parallel.md
rules/bundle-barrel-imports.md
各ルールファイルの内容:
- 重要である理由の簡単な説明
- 説明付きの誤ったコード例
- 説明付きの正しいコード例
- 追加のコンテキストと参考資料
完全版ドキュメント
すべてのルールを展開した完全ガイド:AGENTS.md