Lighthouseパフォーマンス改善記録
本番環境(https://log.eurekapu.com/)のLighthouse測定結果に基づくパフォーマンス改善の記録。
測定日時
- 初回測定: 2025-12-04
改善前の状態
全体スコア
| ページ | Performance | Accessibility | Best Practices | SEO |
|---|---|---|---|---|
| / | 96 | 100 | 100 | 91 |
| /about | 98 | 100 | 100 | 91 |
| /blog | 43 | 95 | 100 | 91 |
/blog ページのパフォーマンスが特に低い。
/blog ページの詳細分析
Core Web Vitals
| 指標 | 値 | 基準 | 状態 |
|---|---|---|---|
| First Contentful Paint (FCP) | 8.6秒 | < 1.8秒 | ❌ |
| Largest Contentful Paint (LCP) | 10.4秒 | < 2.5秒 | ❌ |
| Total Blocking Time (TBT) | 550ms | < 200ms | ⚠️ |
| Cumulative Layout Shift (CLS) | 0 | < 0.1 | ✅ |
| Speed Index | 8.8秒 | < 3.4秒 | ❌ |
問題点(DIAGNOSTICS)
- Reduce initial server response time
- サーバー応答時間: 1,960ms(約2秒)
- 原因: サーバーサイドでの記事一覧取得・レンダリング処理
- Largest Contentful Paint element
- LCP要素の表示に10,390ms
- 原因: サーバー応答遅延の影響
- Eliminate render-blocking resources
- 削減可能: 750ms
- 原因: CSS/JSのレンダーブロッキング
- Reduce unused JavaScript
- 削減可能: 24 KiB
- 原因: 未使用のJSコードがバンドルに含まれている
- Avoid long main-thread tasks
- 5個の長いタスクを検出
- 原因: JavaScriptの実行時間が長い
- Serve static assets with efficient cache policy
- 1リソースでキャッシュ設定不足
その他の問題
- SEO (91点):
robots.txt is not valid- robots.txtにエラーあり - Accessibility (95点): コントラスト比が不十分な箇所あり
改善計画
優先度: 高
| # | 対策 | 期待効果 | 難易度 |
|---|---|---|---|
| 1 | サーバー応答時間の改善 | FCP/LCP大幅改善 | 中 |
| 2 | robots.txtのエラー修正 | SEO改善 | 低 |
優先度: 中
| # | 対策 | 期待効果 | 難易度 |
|---|---|---|---|
| 3 | レンダーブロッキングリソースの最適化 | 750ms削減 | 中 |
| 4 | 未使用JavaScriptの削減 | 24KiB削減 | 低 |
優先度: 低
| # | 対策 | 期待効果 | 難易度 |
|---|---|---|---|
| 5 | キャッシュポリシーの最適化 | リピートアクセス高速化 | 低 |
| 6 | コントラスト比の改善 | A11y向上 | 低 |
実装内容
1. サーバー応答時間の改善
実施日: 2025-12-04
原因分析:
/blog ページでは queryCollection('pages').all() を使用して、130件以上のコンテンツを全フィールド取得していた。
// 改善前: 全フィールドを取得
const { data: contentArticles } = await useAsyncData('blog-content-articles', () =>
queryCollection('pages').all()
)
問題点:
- 全130ファイルの全フィールド(本文含む)を取得
- クライアント側でソート処理を実行
- 不要なデータ転送によるレスポンス遅延
実装:
- 必要なフィールドのみ選択(
select()) - DB側でソート(
order())
// 改善後: 必要なフィールドのみ、DB側でソート
const { data: contentArticles } = await useAsyncData('blog-content-articles', () =>
queryCollection('pages')
.select('title', 'description', 'path', 'tags', 'publishedAt')
.order('publishedAt', 'DESC')
.all()
)
コード変更:
apps/web/app/pages/blog/index.vue:12-18
2. robots.txtのエラー修正
実施日: 2025-12-04
原因分析:
実装:
改善結果
改善後のスコア
| ページ | Performance (前) | Performance (後) | 改善幅 |
|---|---|---|---|
| / | 96 | 99 | +3 |
| /about | 98 | 97 | -1 |
| /blog | 43 | 96 | +53 |
全体平均
| 指標 | 改善前 | 改善後 |
|---|---|---|
| Performance | 79 | 97 |
| Accessibility | 98 | 98 |
| Best Practices | 100 | 100 |
| SEO | 91 | 91 |
改善の効果
/blog ページのパフォーマンスが 43 → 96 に大幅改善(+53ポイント)。
主な要因:
- サーバー応答時間の短縮(クエリ最適化による)
- データ転送量の削減(必要なフィールドのみ取得)
学んだこと
- クエリの最適化が重要:
queryCollection().all()は全フィールドを取得するため、大量のコンテンツがある場合はselect()で必要なフィールドのみ取得する - DB側でのソートが効率的: クライアント側でソートするより、
order()でDB側でソートした方が効率的 - 開発サーバー vs 本番の差: 開発サーバーでのスコアは本番より大幅に低くなる。正確な測定には本番環境を使用すべき
- Lighthouse CIの活用: ローカルで簡単に本番環境のパフォーマンスを測定できる。デプロイ前後の比較に有用