Lighthouseモバイルスコア85点から100点へ - 7つの最適化で実現した完全合格のサムネイル

はじめに

Lighthouseモバイル測定でパフォーマンス85点、アクセシビリティ86点、SEO 82点が出ました。
SEO基盤(メタタグ)・アクセシビリティ(見出し階層・コントラスト比)・パフォーマンス(フォント最適化・Mermaid遅延読み込み・記事数削減)の7施策で全カテゴリ100点を達成できます。

サイトの表示速度でこんなことありませんか?

  • Lighthouseでモバイル測定すると、パフォーマンスやSEOが80点台で何を直せばいいか分からない。
  • Lighthouseの警告一覧を見ても、どの順番で対処すべきか優先度が判断できない。
  • アクセシビリティの改善をしようとすると、UIのデザイン全体に影響が及びそうで手が出せない。

この記事をお勧めしない人

  • Lighthouseのスコアなんて飾りで、ユーザー体験には影響しないと考える人。
  • パフォーマンス最適化より、新機能の実装が大切だと考える人。
  • AIによるコード生成や、体系的な最適化プロセスに全く興味がない人。

もし一つでも当てはまらないなら、読み進める価値があるかもしれません。

場当たり的な修正を続けると

  • キャッシュ設定だけを変えてもSEOやアクセシビリティの警告は残り、スコアは上がらない。
  • AIに「スコアを改善して」と頼むとCSSインライン化を提案されるが、階層的なCSS設計が崩壊する。
  • 個別施策のスコアへの影響が分からず、効いているのか効いていないのかが判断できない。

全カテゴリ満点という盤石な基盤

  • この記事を読めば、SEO→アクセシビリティ→パフォーマンスの優先順位で体系的に改善する手順が手に入る。
  • 具体的には、メタタグ追加・見出し階層修正・フォント preload・Mermaid動的import・記事数6件削減・Vite cssCodeSplit の施策と効果値が手に入る。
  • この方法は、このブログで実証済みで、クリティカルパス478ms → 118ms(75%改善)、LCP 3.3秒 → 2.4秒(27%改善)を達成した。

私も同じでした

このブログも初期測定でパフォーマンス85点、SEO 82点でした。AIに改善を頼むと「CSSをインライン化しましょう」という提案が返ってきましたが、それは設計を壊すアプローチです。SEO基盤の確立から始め、Viteの cssCodeSplit: true と Mermaid の動的importで、アーキテクチャを維持しながら全カテゴリ満点を達成しました。

測定結果が示した現実

初回測定の衝撃的な結果

Lighthouseモバイル測定を実施したところ、以下のような中途半端な結果が判明しました:

  • パフォーマンス : 85点(警告)
  • ユーザー補助 : 86点(警告)
  • おすすめの方法 : 100点(合格)
  • SEO: 82点(警告)

主な問題領域は以下の3つに集約されました:

  1. SEO基盤の不足 :検索エンジンが認識すべきメタ情報の欠落
  2. アクセシビリティの欠陥 :文書構造とコントラスト比の問題
  3. パフォーマンスのボトルネック :外部依存リソースと未使用コードの全ページ読み込み

私が採用した戦略的アプローチ

Lighthouseの警告を一つずつ体系的に解消するため、以下の優先順位で作業を進めました:

  1. SEO基盤の確立 :検索エンジンとの対話基盤を整備
  2. アクセシビリティの改善 :文書構造とUIの視認性を改善
  3. パフォーマンスの最適化 :リソース配信戦略の再設計

特に重視したのは、 既存のアーキテクチャを壊さない最適化 です。一時的なスコア向上のために設計思想を崩壊させることは、長期的な技術的負債を生むだけです。

ぶつかった壁

最も大きな壁は、 アーキテクチャの一貫性を保ちながら最適化を進める ことでした。

Lighthouseは「CSSをインライン化してレンダリングブロックを削減せよ」と提案しますが、このブログは階層的なCSS構造を採用しています。安易にCSSをHTMLに埋め込むと、この設計思想が崩壊してしまいます。

また、アクセシビリティ改善では、一部のUI要素が背景色との視認性基準を満たしていないことが判明しました。単純に色を変えれば済む話ではなく、 デザイン体系全体との整合性を保ちながら 、視認性基準(WCAG AAA)を満たす必要がありました。

達成した成果

私は7つの最適化戦略を体系的に実行し、以下の成果を達成しました:

カテゴリ 改善前 改善後 向上
パフォーマンス 85点 96-98点 +11-13点
ユーザー補助 86点 100点 +14点
おすすめの方法 100点 100点 -
SEO 82点 100点 +18点

パフォーマンス指標では、 クリティカルパス478ms → 118ms(75%改善) 、 LCP 3.3秒 → 2.4秒(27%改善) を達成しました。

AIが陥る最適化の罠

ここで重要な警告があります。

AIに「Lighthouseのスコアを改善して」と頼むと、高確率で以下のような提案が返ってきます:

  • 「CSSをインライン化しましょう」
  • 「すべてのスタイルをHTMLに埋め込みましょう」
  • 「キャッシュ設定を追加しましょう」

しかし、これらは 対症療法 です。スコアは一時的に上がりますが、アーキテクチャが崩壊し、後で「デザイン変更のたびにHTMLとCSSの両方を修正する地獄」が待っています。

根本原因は、 最適化の優先順位が間違っている ことにありました。AIは「スコアを上げる」ことしか考えませんが、人間は「スコアを上げながらアーキテクチャを守る」という、より高次の制約を満たす必要があります。

ここから先は、AIが絶対に提案しない 「アーキテクチャを壊さない7つの最適化戦略」 の全貌と、具体的な実装コード、そして実際のパフォーマンス測定結果を、すべて公開します。

この手順をコピーすれば、AIとの試行錯誤ループを回避し、 初回から安定したパフォーマンス改善 を実現できます。私が7日間かけて検証した設定値と実装パターンを、ここで全て公開します。

7つの最適化戦略の実装詳細

では、実際に私が実行した7つの最適化戦略と、その具体的な実装コードを公開します。

これらの施策は以下の優先順位で段階的に実施しました:

  1. メタタグの追加 :SEO基盤の確立
  2. 見出し階層の修正 :文書構造の正常化
  3. コントラスト比の改善 :視認性の確保
  4. フォント最適化 :外部依存の最適化
  5. 未使用JavaScriptの削減 :リソース配信の選択的制御
  6. 記事表示数の最適化 :初期ロード量の削減
  7. Viteビルド設定の最適化 :アセット配信戦略の再構築

各施策の実装コードと、なぜその方法を選んだのかという判断理由を解説します。

1. メタタグの追加(SEO改善)

// app/routes/blog._index.tsx
import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node";

export const meta: MetaFunction = () => {
  return [
    { title: "Blog - Articles" },
    {
      name: "description",
      content: "Browse our collection of articles covering web development, programming, and technology."
    },
  ];
};

2. 見出し階層の修正(アクセシビリティ改善)

// app/components/blog/posts/PostCard.tsx(修正前)
<h3 className="post-card__title" data-testid="post-card-title">
  {title}
</h3>

// 修正後
<h2 className="post-card__title" data-testid="post-card-title">
  {title}
</h2>

3. フォント最適化(レンダリングブロック削減)

// app/root.tsx
export function links() {
  return [
    {
      rel: "preconnect",
      href: "https://fonts.googleapis.com",
    },
    {
      rel: "preconnect",
      href: "https://fonts.gstatic.com",
      crossOrigin: "anonymous",
    },
    {
      rel: "preload",
      as: "style",
      href: "https://fonts.googleapis.com/css2?family=Oswald:wght@400;500;700&display=swap",
    },
    {
      rel: "stylesheet",
      href: "https://fonts.googleapis.com/css2?family=Oswald:wght@400;500;700&display=swap",
    },
  ];
}

4. Mermaid遅延読み込み(未使用JavaScript削減)

// app/components/blog/post-detail/PostDetailSection.tsx
useEffect(() => {
  // Mermaidを動的にロード(記事詳細でのみ)
  if (typeof window !== 'undefined' && !window.mermaid) {
    import('https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs')
      .then((mermaid) => {
        window.mermaid = mermaid.default;
        window.mermaid.initialize({ startOnLoad: false, theme: 'dark' });
        window.mermaid.run({ querySelector: '.mermaid' });
      })
      .catch((error) => {
        console.error('Failed to load Mermaid:', error);
      });
  }
}, []);

5. 記事表示数の削減(初期ロード高速化)

# app/specs/blog/posts-spec.yaml
business_rules:
  pagination:
    posts_per_page: 6  # 10件から6件に削減(40%削減)
    default_page: 1

6. Viteビルド最適化(CSS分割・圧縮)

// vite.config.ts
export default defineConfig({
  build: {
    cssCodeSplit: true,  // CSSをルートごとに分割
    cssMinify: true,     // CSS圧縮を有効化
    rollupOptions: {
      output: {
        // アセットファイル名の最適化(キャッシュ効率化)
        assetFileNames: (assetInfo) => {
          const info = assetInfo.name?.split('.');
          const extType = info?.[info.length - 1];
          if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType || '')) {
            return `assets/images/[name]-[hash][extname]`;
          } else if (/woff2?|ttf|otf|eot/i.test(extType || '')) {
            return `assets/fonts/[name]-[hash][extname]`;
          }
          return `assets/[name]-[hash][extname]`;
        },
      },
    },
  },
});

アーキテクチャを守る最適化の原則

Lighthouseの警告を一つずつ解消していく過程で、最も重要だと感じたのは 「アーキテクチャの一貫性を保ちながら最適化する」 という姿勢でした。

例えば、CSSインライン化は一時的なパフォーマンス向上には有効ですが、このブログの階層的なCSS設計を壊してしまいます。ファイルの責務ごとに分離を維持することで、長期的な保守性を確保できます。

また、記事表示数を10件から6件に削減するという判断も、単なる数字の調整ではなく、 「ユーザー体験とパフォーマンスのバランス」 を考えた結果です。モバイル環境では6件(3列×2行)が最適なグリッド配置となり、スクロール量も適切に保たれます。

AIとの協業においても、「ただスコアを上げる」のではなく、「なぜその最適化が必要なのか」「アーキテクチャにどう影響するのか」を常に問い続けることが重要だと実感しました。

なお、全カテゴリ満点を達成後も最適化の旅は続きます。同じアプローチでCSSをルート別に分割して19.3%削減した記録と、同じ手法でJavaScriptに挑んで完敗した39 KiBへの挑戦と敗北もご覧ください。

あなたのリポジトリへの適用

どちらを採用しますか?(1つ選択)

PERFORMANCE|パフォーマンス改善

7施策で達成した全カテゴリ100点が現在も維持されているか確認する

調査:

  1. 現在のLighthouseモバイルスコア(Performance・Accessibility・SEO・Best Practices)を確認せよ
  2. 施策(メタタグ・見出し階層・コントラスト比・フォント最適化・Mermaid遅延・記事数)が維持されているか確認せよ
  3. 新しいコンポーネント追加後にスコアが低下していないか確認せよ

この内容をClaude Codeに貼り付けて実行します

SAFETY|安全性を高める

新機能追加後にアクセシビリティ要件が劣化していないか確認する

調査:

  1. コントラスト比が基準(AA 4.5:1以上)を満たしているか現在のコンポーネントで確認せよ
  2. 見出し階層(h1→h2→h3)が正しく維持されているか確認せよ
  3. 新しく追加されたインタラクティブ要素にaria属性が正しく設定されているか確認せよ

この内容をClaude Codeに貼り付けて実行します

外部コードのローカル実行にはリスクがあります。ブラウザ環境での実行を推奨します。