delay-hydration
nuxt-delay-hydration

ハイドレーションを遅延させることで、Nuxt v2 の Google Lighthouse スコアを向上させます。

nuxt-delay-hydration

NPM Downloads


ステータス: 安定版 v2 v0 ✅ , v3 メイン
私のスポンサープログラム💖によって実現しました
フォローしてください @harlan_zw 🐦

⚠️ これは、Google Lighthouse にサイトが実際よりも高速であると錯覚させるための「ハック」です。

  • これは、プログレッシブエンハンスメントされたウェブサイトにのみ使用してください。
  • 実際のパフォーマンスや SEO のメリットは得られない可能性があります(Google Lighthouse ではなく、CrUX でテストしてください)。

機能

  • 🔥 サイトの「ブロッキング時間」を削減します
  • 🚦 ルートルールを使用したページレベルごとの設定
  • 🔁 (オプション)ハイドレーション前のクリックをリプレイします

なぜハイドレーションを遅延させるのか?

ハイドレーションを遅延させることは、スクリプトがアプリの機能に必要ないことを Google に示すための手法です。

ハイドレーションを遅延させることで、「ブロッキング時間」メトリックを削減し、Google Lighthouse スコアを向上させます。

以前は、vue-lazy-hydration を使用していたかもしれませんが、これはうまく機能します。しかし、このモジュールで行っているように、Google にヒントを与えるより冗長な方法にすぎません。


プログレッシブエンハンスメントされたアプリとは?

プログレッシブエンハンスメントされたアプリとは、JavaScript なしで動作するように設計され、その後 JavaScript で段階的に機能が向上されるアプリです。

スクリプトはウェブサイトを使用するために必要であるべきではありません。これが、ハイドレーションを遅延させることで Google に示していることです。

そのためには、以下を確実にする必要があります。

  • 最初のレスポンスで完全な HTML が提供される
  • スクリプトが CLS をトリガーしない
  • スクリプトを使用して画像をセットアップするのを避ける。これは LCP に影響します

このモジュールの仕組み
プロミスがアプリに挿入され、その場所はモードに基づいています。プロミスは、以下のいずれかのイベントが発火するとすぐに解決されます。
  • インタラクションイベント(マウスの動き、スクロール、クリックなど)
  • 固定タイムアウトを持つアイドルコールバック

アイドル CPU 時間は、これらのスクリプトがアプリの実行に必要ないことを Google に示します。

例:

  • Google ボットがページを訪問し、インタラクションがない場合、ブラウザのアイドルコールバック + 6 秒が経過するまで、ハイドレーションはデフォルトでは発生しません。
  • ユーザーがページを訪問してカーソルを動かしたりスクロールしたりすると、ハイドレーションがすぐにトリガーされます。非ハイドレーションアプリとのインタラクションの可能性は最小限に抑えられます。

これはハッキング的な解決策であることに注意してください。Google がプログレッシブスクリプトエンハンスメントを認識できるようになるまでは、このアプローチに頼る必要があります。


インストール

Nuxt 2.x を使用している場合は、v0 ブランチのドキュメントに従ってください。⚠️ Nuxt 2 は非推奨であり、サポートは受けられません。

npx nuxi@latest module add delay-hydration

要件: プログレッシブエンハンスメントされた SSR または SSG Nuxt アプリ。


使用方法

// nuxt.config.ts
export default {
  modules: [
    'nuxt-delay-hydration',
  ],
  delayHydration: {
    // enables nuxt-delay-hydration in dev mode for testing
    // NOTE: you should disable this once you've finished testing, it will break HMR
    debug: process.env.NODE_ENV === 'development'
  }
}

注意: デバッグを有効にしない限り、開発環境ではモジュールは実行されません。

モードの選択

デフォルトでは、モードは選択されていません。モジュールがどのように動作するかを選択する必要があります。

タイプ: init | mount| manual | false

デフォルト: false

タイプ説明ユースケース
false デフォルトモジュールを無効にするテスト
initすべてのスクリプトの読み込みを遅延させます。プラグイン/モジュールはゼロまたは最小限です。
mount 推奨Nuxt がマウントされている間、遅延させます。プラグインと一部のサードパーティースクリプトは動作します。最小限の重要でないプラグインとサードパーティーのプラグイン。
manual遅延は DelayHydration コンポーネントによって提供されます。他のすべてのアプリ

選択したモードに関係なく、さらなる最適化を読んでください。

Init モード

このモードは、ハイドレーションのプロミスが解決されるまで、すべてのスクリプトの読み込みを遅延させます。

これは、HTML レンダリングにフックし、すべてのスクリプトタグを削除し、ハイドレーションのプロミスが解決された後にそれらを再度追加することで行われます。

これにより、最大の速度向上が得られますが、最もリスクが高いです。

利点: 最大のブロッキング時間削減を提供します

欠点: 重要なサードパーティースクリプトがある場合、リスクが高いです

ベンチマーク: 約 90-100% の削減

export default {
  delayHydration: {
    mode: 'init'
  }
}

Mount モード

このモードは、Nuxt がマウントされている間、遅延させます。プラグインと一部のサードパーティースクリプトは動作します。

これはレイアウトとページコンポーネントを遅延させます。

利点: より安全で、依然として良好な改善を提供します

欠点: JavaScript に依存する特定のレイアウトを破損する可能性があります。

ベンチマーク: 約 70% の削減

export default {
  delayHydration: {
    mode: 'mount'
  }
}

Manual モード

手動モードを使用すると、アプリのどの部分を遅延させたいかを手動で指定できます。ナビゲーションドロワーのように、ページの特定の部分を常にすぐにハイドレーションする必要がある場合に便利です。

利点: 最も安全な最適化方法

欠点: 使用状況に基づく速度向上

export default {
  delayHydration: {
    mode: 'manual'
  }
}

DelayHydration コンポーネント

モードを設定したら、コンポーネントを使用する必要があります。

<template>
  <div>
    <DelayHydration>
      <div>
        <LazyMyExpensiveComponent />
      </div>
    </DelayHydration>
  </div>
</template>

ガイド

ページごとの設定

ルートルールを使用して、ページごとにモジュールを設定できます。

// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    // delay the home page
    '/': { delayHydration: 'mount' },
    // disable the module for the admin
    '/admin/': { delayHydration: false }
  }
})

defineRouteRules を使用して、ページレベルで定義することもできます。

デバッグ

デバッグモード
本番環境にデプロイする前に、モジュールを使用してアプリで徹底的なテストを行うことをお勧めします。

モジュールが期待通りに動作していることを確認するために、debug モードがあり、有効にするとコンソールに動作がログされます。

ローカル環境で常にデバッグを行うのは良い考えかもしれません。その場合、以下のようにできます。

export default defineNuxtConfig({
  delayHydration: {
    debug: process.env.NODE_ENV === 'development',
  },
})

ハイドレーションステータスの視覚化
アプリがかなり静的である場合、ハイドレーションされているかどうか不明瞭なことがあり、デバッグが難しくなる可能性があります。

これを簡単にするために、何が起こっているかを示す HydrationStatus コンポーネントがあります。

<template>
  <div>
    <MyHeader />
    <DelayHydration>
      <div>
        <!-- Show the hydration status, only for debugging -->
        <HydrationStatus />
        <main>
          <nuxt />
        </main>
        <my-footer />
      </div>
    </DelayHydration>
  </div>
</template>

パフォーマンス監査

私の監査ツールを使用してください: https://unlighthouse.dev/

ハイドレーションクリックのリプレイ

これは何で、どのように有効にするか
ハイドレーションを遅延させる問題の1つは、スクリプトが読み込まれる前にユーザーインタラクションイベントが発生する可能性があり、ユーザーが期待する動作をするまでに何度もクリックしなければならないことです。JavaScript を使用してトリガーされるハンバーガーメニューを考えてみてください。アプリがハイドレーションされていない場合、それをクリックしても何も起こりません。

これに対する最善の解決策は、JavaScript を必要としない方法で HTML を記述することです。

ただし、JavaScript を使用する必要があり、最初のクリックに応答することが重要なユースケースもあります。そのような場合は、クリックのリプレイを有効にすることができます。

export default defineNuxtConfig({
  delayHydration: {
    replayClick: true
  },
})

これは実験的な設定です。本番アプリに実装する前に、このオプションを自分でテストする必要があります。

さらなる最適化

重いコンポーネントを非同期で読み込む
重いコンポーネントを同期的に読み込むと、JavaScript はメインアプリケーションのペイロードにバンドルされます。

これにより、すべてのパフォーマンスメトリックが低下します。これらのコンポーネントには非同期インポートを使用することをお勧めします。

大きなコンポーネントを見つけるには nuxi analyze を実行します。それらを読み込む際には、Lazy をプレフィックスとして付けてください。

高度な設定

設定は、Nuxt 設定内の delayHydration キーで提供する必要があります。

ラボまたは フィールドデータのパフォーマンスが良くないと感じた場合は、この高度な設定をいじってみることをお勧めします。

ルートのフィルタリング

注意: これらのフィルタリングオプションの代わりにルートルールを使用することをお勧めします。

include および exclude オプションを使用すると、ハイドレーションを遅延させるルートを指定できます。

// nuxt.config.ts
export default defineNuxtConfig({
  delayHydration: {
    include: [
      '/blog/**',
    ],
    exclude: [
      '/admin/**'
    ],
  },
})

ルートルールと同様にグロブパターンまたは正規表現を提供できます。

イベントハイドレーション

hydrateOnEvents

  • タイプ: string[]
  • デフォルト: [ 'mousemove', 'scroll', 'keydown', 'click', 'touchstart', 'wheel' ]

ハイドレーションを再開させるブラウザイベントを制御します。デフォルトでは、起こりうるユーザーエクスペリエンスの問題を避けるために非常に積極的です。

replayClick

  • 型: boolean
  • デフォルト: false

ハイドレーションのトリガーがクリックであった場合、それをリプレイできます。リプレイすると、アプリがハイドレーションされたと推定されるときにイベントが再実行されます。

例えば、ユーザーがハンバーガーアイコンをクリックし、メニューを開くためにハイドレーションが必要な場合、ハイドレーション後にクリックがリプレイされます。

⚠️ これは実験的な機能です。注意して使用してください。

アイドルハイドレーション

idleCallbackTimeout

  • タイプ: number (ミリ秒)
  • デフォルト: 7000

アイドルコールバックを待つ際、待機する最大時間をミリ秒で定義できます。これは、多くのネットワークリクエストが発生している場合に便利です。

postIdleTimeout

  • タイプ: { mobile: number, desktop: number } (ミリ秒)
  • デフォルト: { mobile: 5000, desktop: 4000, }

アイドルコールバックの後、ハイドレーションを再開するまでに待機する時間(ミリ秒)。この追加のタイムアウトは、標準的な「ブロッキング」を避けるために必要です。Lighthouse に実際のアイドル時間を提供する必要があります。

モバイルの CPU 容量はデスクトップよりもはるかに少ないため、モバイルは常にデスクトップよりも高く設定する必要があります。

注意: デフォルト値は、将来のベンチマークに基づいてカスタマイズされる可能性があります。

デバッグ

debug

  • 型: boolean
  • デフォルト: false

ハイドレーションがブロックされたとき、およびブロックが解除されたときとその理由について、詳細をコンソールにログします。

ベンチマーク

ライブの例

クレジット

スポンサー

ライセンス

MITライセンス © 2022 - 現在 Harlan Wilton