👏

Core Web Vitalsとは? Next.js導入検討でわかったこと

に公開

はじめに

技術選定でReact + Railsの導入を考えていたとき、フロントつよつよエンジニアに相談したところ「SEO対策を考えるならNext.jsを入れた方がいい」とアドバイスをもらいました。

その理由がCore Web Vitalsでした。

つよつよエンジニアと話すとき、知らない単語に出会います。そんなとき私みたいなよわよわエンジニアにできることは黙ってキャッチアップすることのみ。

「Core Web Vitalsって何?」「なぜNext.jsなの?」

この記事では、その疑問を解説します。

Core Web Vitalsとは

Core Web Vitalsは、Googleが定めたユーザー体験を測る3つの指標です。2021年から検索ランキングの要素として正式に採用されています。

3つの指標:

  1. LCP(Largest Contentful Paint) - 表示速度
  2. INP(Interaction to Next Paint) - 応答性
  3. CLS(Cumulative Layout Shift) - 視覚的安定性

ここを対策すれば検索時に上に来る確率が上がります。
私のチームもリードタイムや変更障害率などの指標で測られますが、サイトたちも上記のような数値で測られるのかと思うと少し親近感がわきました。

1. LCP(表示速度)

LCPとは

ページのメインコンテンツが表示されるまでの時間です。
良好: 2.5秒以内
改善が必要: 2.5〜4秒
不良: 4秒以上

なぜReact + Railsだと問題になるのか

通常のReact(SPA)では、以下の流れでページが表示されます:

1,HTMLを読み込む(ほぼ空っぽ)
2,JavaScriptを読み込む
3,JavaScriptが実行される
4,APIからデータを取得
5,やっと画面が表示される

Next.jsならどう改善されるか

Next.jsのSSR(サーバーサイドレンダリング)では:

1,サーバーで完成したHTMLを生成
2,すぐに画面が表示される
3,JavaScriptで機能を追加(ハイドレーション)

最初からコンテンツが表示されるため、LCPが大幅に改善されます。

改善方法

画像の最適化

// Next.jsのImage コンポーネント
import Image from 'next/image'

// 悪い例(通常のReact)
<img src="/wine.jpg" alt="ワイン" />

// 良い例(Next.js)
<Image 
  src="/wine.jpg" 
  alt="ワイン"
  width={800}
  height={600}
  priority  // 優先読み込み指定
/>

priorityがないと**遅延読み込み(lazy loading)**ですが、メインの画像などにpriorityをつけると、優先的に読み込まれLCPが速くなります。

2. INP(応答性)

INPとは

ユーザーの操作に対してページが反応するまでの時間です。
良好: 200ms以内
改善が必要: 200〜500ms
不良: 500ms以上

Next.jsでの改善
コード分割が自動

// ページごとに自動で分割される
// pages/wines/index.js
export default function WineList() {
  return <div>ワインリスト</div>
}

// pages/wines/[id].js
export default function WineDetail() {
  return <div>ワイン詳細</div>
}

必要なコードだけ読み込むため、JavaScriptのサイズが小さくなり、応答性が向上します。
動的インポート

// 重いコンポーネントは動的に読み込む
import dynamic from 'next/dynamic'

const HeavyChart = dynamic(() => import('../components/Chart'), {
  loading: () => <p>読み込み中...</p>
})

3. CLS(視覚的安定性)

CLSとは

ページ読み込み中にレイアウトがズレる量を測る指標です。
良好: 0.1以下
改善が必要: 0.1〜0.25
不良: 0.25以上

よくある問題

<!-- 悪い例:画像のサイズ指定なし -->
<img src="/wine.jpg" alt="ワイン">
<!-- 画像が読み込まれると、下のコンテンツがガクッと下に移動 -->
Next.jsでの改善
javascript// 良い例:サイズを指定
<Image 
  src="/wine.jpg" 
  alt="ワイン"
  width={800}
  height={600}
/>

サイズを指定することで、画像読み込み前にスペースが確保され、レイアウトシフトが起きません。

React + Railsとの比較

項目 React + Rails Next.js + Rails
LCP △(CSRで遅い) ○(SSRで速い)
SEO △(工夫が必要) ○(標準対応)
セットアップ やや複雑 簡単
画像最適化 手動 自動
デプロイ 2箇所 フロントは1コマンド
// pages/wines/[id].js
export async function getServerSideProps({ params }) {
  // サーバー側でAPIを叩く
  const res = await fetch(`http://localhost:3000/api/wines/${params.id}`)
  const wine = await res.json()
  
  return { props: { wine } }
}

export default function WineDetail({ wine }) {
  return (
    <div>
      <h1>{wine.name}</h1>
      <Image 
        src={wine.image} 
        alt={wine.name}
        width={600}
        height={400}
        priority
      />
      <p>{wine.description}</p>
    </div>
  )
}

Core Web Vitalsの測定方法

  1. PageSpeed Insights(これが一番かんたんでした)
    https://pagespeed.web.dev/
    URLを入力するだけで、3つの指標が測定できます。

  2. Chrome DevTools

    1. Chromeで対象サイトを開く
    2. F12でDevToolsを開く
    3. Lighthouse タブ
    4. 「レポートを生成(Analyze page load)」をクリック
  3. Next.jsの組み込みツール

// next.config.js
module.exports = {
  experimental: {
    webVitalsAttribution: ['CLS', 'LCP', 'INP']
  }
}

まとめ

Core Web Vitalsは、SEO対策に欠かせない指標です。

3つの指標
LCP: 表示速度(2.5秒以内が理想)
INP: 応答性(200ms以内が理想)
CLS: 視覚的安定性(0.1以下が理想)

Next.jsを選ぶメリット
1,SSRで初回表示が速い
2,自動最適化機能が豊富
3,SEOに強い

Discussion