Nuxt Nation カンファレンス開催!11月12日-13日、ご参加ください。

delay-hydration
nuxt-delay-hydration

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

nuxt-delay-hydration

NPM Downloads


ステータス: 安定版 v2 v0 ✅ , v3 main
私のスポンサー プログラム 💖 によって実現しました
フォローしてください @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を遅らせます。プラグインと一部のサードパーティスクリプトは機能します。重要なでないプラグインとサードパーティプラグインを最小限に抑えます。
manualDelayHydrationコンポーネントによって遅延が提供されます。その他のすべてのアプリ

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

Initモード

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

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

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

長所:ブロッキング時間の削減が最大になります

短所:重要なサードパーティスクリプトがある場合はリスクがあります

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

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

Mountモード

このモードは、マウント中にNuxtを遅らせます。プラグインと一部のサードパーティスクリプトは機能します。

レイアウトとページコンポーネントを遅らせます。

長所:安全で、それでも優れた改善を提供します

短所:jsに依存する特定のレイアウトを壊す可能性があります。

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

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

Manualモード

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/**'
    ],
  },
})

ルートルールと同様のglobパターンまたは正規表現を指定できます。

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

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 License © 2022 - 現在 Harlan Wilton