web-performance について
web-performanceは、Apollo、Redis、CloudFront、S3を使うWebアプリ向けのパフォーマンススキルです。キャッシュ、ペイロードとバンドルの削減、Reactの描画、データベースクエリの最適化を扱います。
主な機能
- 01Apollo Clientのキャッシュポリシー
- 02Redisのキャッシュと無効化パターン
- 03CloudFrontとS3のアセットキャッシュ
- 04ルート単位のコード分割
- 05Reactの描画最適化
- 06データベースクエリとインデックスの指針
活用シーン
- 01更新頻度に応じてキャッシュポリシーを設定する場面
- 02初期JavaScriptバンドルを縮小する場面
- 03CloudFrontとS3で画像配信を最適化する場面
- 04遅いクエリやN+1アクセスを調査する場面
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ alexanderstephenthompson/ claude-hub --skill web-performanceインストール後、Claude Code で/web-performanceを入力して読み込まれたか確認します。
同梱ファイルassets/caching-patterns.mdassets/optimization-patterns.md
詳細
Web パフォーマンススキル
バージョン: 1.0 スタック: Apollo Client/Server + Redis + CloudFront + S3
開発中はパフォーマンスの問題が見えません。ローカルサーバーは高速です。テストデータは少量です。実際のデータを使い、実際の接続環境で利用するユーザーから、ページの読み込みに8秒かかると報告されるまで、3MBのバンドル、N+1クエリ、フルテーブルスキャンには気付きません。その時点では、プレッシャーのかかる状況で、キャッシュレイヤーの再設計、バンドルの分割、クエリの書き直しを一度に行わなければなりません。
最初から適用するパフォーマンスパターンは、低コストです。リリース後に行うパフォーマンスの修正は高くつきます。以下のルールは、低コストで済む方法です。
基本原則
- まず計測する — 最適化の前にプロファイリングします。推測で判断しないでください。
- すべてのレイヤーでキャッシュする — CDN → API → データベース → インメモリ。
- ペイロードを最小限にする — 必要なものだけを送信します。
- 重要でない処理は後回しにする — 重要な処理を最初に読み込み、それ以外は後から読み込みます。
- 体感パフォーマンスを高める — 楽観的 UI によって、動作が速く感じられます。
Core Web Vitals の目標値
| 指標 | 測定対象 | 目標値 | 要注意 |
|---|---|---|---|
| LCP (Largest Contentful Paint) | メインコンテンツの読み込み | < 2.5s | < 4s |
| INP (Interaction to Next Paint) | 入力への応答性 | < 200ms | < 500ms |
| CLS (Cumulative Layout Shift) | 視覚的な安定性 | < 0.1 | < 0.25 |
Apollo Client のキャッシュ
InMemoryCache にページネーションのマージや計算フィールド用のタイプポリシーを設定します。デフォルトのフェッチポリシーには cache-and-network(stale-while-revalidate)を使用します。ミューテーションには楽観的更新を使い、UI が即座に反応するようにします。
フェッチポリシー
| ポリシー | 用途 |
|---|---|
cache-first | 静的データ(カテゴリ、設定) |
cache-and-network | 変更されるデータ(商品、ユーザーデータ) |
network-only | 常に最新のデータ(注文状況、リアルタイムデータ) |
cache-only | オフラインモード、キャッシュ済みと分かっているデータ |
キャッシュ設定、フェッチポリシーの例、楽観的更新のパターンについては、assets/caching-patterns.md を参照してください。
Redis キャッシュ
キャッシュアサイドパターン:キャッシュを確認 → ミス → DB から取得 → キャッシュに保存します。書き込み時に無効化します。リストクエリにはタグベースの無効化を使用します。
TTL のガイドライン
| データの種類 | TTL | 理由 |
|---|---|---|
| 静的設定 | 24h+ | 変更頻度が低い |
| 商品カタログ | 1h | たまに変更される |
| ユーザーセッション | 30m | セキュリティとのバランス |
| カートデータ | 7d | ユーザーの利便性 |
| 検索結果 | 5m | 最新性と速度のバランス |
| リアルタイムデータ | キャッシュなし | 常に最新である必要がある |
Redis キャッシュサービス、キャッシュアサイドパターン、無効化の例については、assets/caching-patterns.md を参照してください。
CloudFront と S3 の最適化
イミュータブルなアセット(ハッシュ付きファイル名)は365日間キャッシュします。API ルートは CDN キャッシュを使用しません。画像はオンデマンドでリサイズし、WebP 形式、遅延読み込み、Retina ディスプレイ向けの 2x srcSet を使用します。
CDK の設定と画像最適化コンポーネントについては、assets/caching-patterns.md を参照してください。
バンドルの最適化
React.lazy を使ってルートベースでコード分割します。重いライブラリには動的インポートを使い、必要なときだけ読み込みます。source-map-explorer で分析します。
バンドルサイズのガイドライン
| カテゴリ | 目標値 | 超過した場合の対応 |
|---|---|---|
| 初期 JS | < 100KB gzip 圧縮後 | コード分割、ツリーシェイキング |
| ベンダーチャンク | < 150KB gzip 圧縮後 | 遅延読み込み、代替手段を検討 |
| ルートチャンク | < 50KB gzip 圧縮後 | さらに分割 |
| 初期読み込みの合計 | < 200KB gzip 圧縮後 | 依存関係を監査 |
コード分割、動的インポート、バンドル分析の例については、assets/optimization-patterns.md を参照してください。
React のパフォーマンス
コストの高い計算には useMemo、メモ化された子コンポーネントに渡すコールバックを安定させるには useCallback、リスト項目のコンポーネントには memo を使用します。単純な値、常に変化する値、メモ化されていない子コンポーネントに渡すハンドラーはメモ化しないでください。長いリスト(100 件以上)には仮想化を使用します。
メモ化、メモ化しない方がよい場合、仮想化の例については assets/optimization-patterns.md を参照してください。
データベースのパフォーマンス
必要なフィールドのみを選択します。include は控えめに使用します。複雑な集計には生クエリを使用します。フィルターやソートに使用する列には複合インデックスを追加します。
Prisma クエリの最適化とインデックス戦略については、assets/optimization-patterns.md を参照してください。
アンチパターン
| アンチパターン | 問題 | 修正方法 |
|---|---|---|
| すべてのフィールドを取得する | 過剰なデータ取得、低速化 | 必要なフィールドのみを選択する |
| ページネーションがない | メモリの問題、低速化 | カーソルベースのページネーション |
| すべてをキャッシュする | 古いデータ、複雑化 | TTL に基づいて戦略的にキャッシュする |
| 時期尚早な最適化 | 労力の無駄 | まず計測し、ボトルネックを最適化する |
| 負荷の高い処理を同期実行する | レスポンスをブロックする | バックグラウンドジョブ(Bull) |
| 静的アセットに CDN を使用しない | グローバル配信が遅い | 静的ファイルには CloudFront を使用する |
| 画像が最適化されていない | ダウンロードサイズが大きい | リサイズ、圧縮、WebP への変換 |
| バンドルがブロッキングする | 初回読み込みが遅い | コード分割、遅延読み込み |
チェックリスト
フロントエンド
- ルートごとにコードを分割する
- 負荷の高いライブラリを遅延読み込みする
- 画像を遅延読み込みする
- 画像を最適化する(WebP、サイズ調整)
- 初回バンドルを 200KB 未満にする
- 有効な箇所で useMemo/useCallback を使用する
- 長いリストを仮想化する
Apollo
- キャッシュポリシーを設定する
- ページネーションのマージが正しく動作する
- ミューテーションにオプティミスティック更新を使用する
- フェッチポリシーがデータの鮮度要件に合っている
Redis
- 頻繁に使うデータをキャッシュする
- データの種類に応じて TTL を設定する
- 更新時にキャッシュを無効化する
- コネクションプーリングを設定する
データベース
- フィルターやソートに使用する列にインデックスを設定する
- 必要なフィールドのみを選択する
- N+1 クエリを解消する(DataLoader)
- コストの高いクエリを分析する
CDN
- 静的アセットを CloudFront に配置する
- 不変のアセットを無期限にキャッシュする
- 動的コンテンツをエッジでキャッシュしない
- HTTPS を必須にする
代替手段を検討する場合
| 状況 | 検討するもの |
|---|---|
| グローバルなリアルタイムデータ | Redis Pub/Sub または WebSockets |
| 負荷の高い計算 | バックグラウンドワーカー(Bull) |
| 大容量ファイルのアップロード | S3 の署名付き URL への直接アップロード |
| 検索が中心 | Elasticsearch または Algolia |
| エッジコンピューティングが必要 | CloudFront Functions または Lambda@Edge |
参考資料
assets/caching-patterns.md— Apollo のキャッシュ設定、Redis、CloudFront、画像の最適化assets/optimization-patterns.md— バンドル分割、React のメモ化、仮想化、データベースの最適化