vitalizer
nuxt-vitalizer

Google LighthouseでのLCPスコアを即座に改善

Nuxt Vitalizer module

Nuxt Vitalizer

Google LighthouseおよびGoogle PageSpeed Insightsにおける最大コンテンツの描画(LCP)を最適化するための、*do-one-thing-well*なNuxtモジュールとしての回避策のコレクション。

このモジュールは、以下のNuxtの問題(その他多数)に対するソリューションを提供します。

機能

  • 🚀 ゼロ設定でLCPを改善
  • 🫸 レンダリングをブロックするCSSを削除

セットアップ

npx nuxi@latest module add nuxt-vitalizer

使用方法

Nuxt VitalizerをNuxtの設定に追加すれば、すぐに利用できます。

// `nuxt.config.ts`
export default defineNuxtConfig({
  modules: ['nuxt-vitalizer']
})

モジュールをカスタマイズするには、Nuxtの設定でvitalizerオプションを設定します。

// `nuxt.config.ts`
export default defineNuxtConfig({
  modules: ['nuxt-vitalizer'],

  vitalizer: {
    // Remove the render-blocking entry CSS
    disableStylesheets: 'entry'
  }
})

LCP最適化機能

このモジュールの最適化機能を適用することで、Lighthouseのパフォーマンススコアを向上させることができます。

Lighthouse SEO performance score when using the module

!NOTE この機能はデフォルトで有効になっています。

大規模なNuxtアプリケーションでは、HTMLに<link rel="prefetch">タグが蓄積されるため、LighthouseおよびGoogle PageSpeed Insightsでパフォーマンススコアが低下することがあります。

非同期コンポーネントや画像などの動的インポートごとに、prefetchリンクがレンダリングされます。これにより、ブラウザはこれらのチャンクを現在のページで必要としない場合でもプリフェッチします。これはアプリケーション全体のパフォーマンスにとっては優れていますが、プリフェッチリクエストの数が多くなり、最大コンテンツの描画スコアに悪影響を及ぼす可能性があります。

このモジュールはNuxtのビルドプロセスにフックし、動的インポートのprefetchリンクのレンダリングを無効にすることで、LCPスコアを最適化します。

!NOTE この機能は手動で有効にする必要があります。

プリロードリンクは、現在のページに必要な重要なリソースをプリロードするために使用されます。一般的にウェブサイトのパフォーマンスを最適化する上で重要な役割を果たしますが、正しく使用しないとリクエスト数が多くなる可能性があります。特に低速なネットワーク条件下では、プリロードリンクを削除することでFCP(First Contentful Paint)スコアを改善するのに役立ちます。

ビルドリソースのプリロードを削除するには、disablePrefetchLinksオプションをtrueに設定します。

// `nuxt.config.ts`
export default defineNuxtConfig({
  modules: ['nuxt-vitalizer'],

  vitalizer: {
    disablePrefetchLinks: true
  }
})

レンダリングをブロックするCSSを停止する

!NOTE この機能は手動で有効にする必要があります。この機能を使用するには、NuxtのinlineStyles機能を有効にする必要があります。このオプションを有効にした後、必ずアプリケーションをテストしてください。

CSSスタイルシートはレンダリングをブロックするリソースであり、ブラウザはページをレンダリングする前にCSSをダウンロードして解析する必要があります。スタイルシートをロードする代わりにインラインスタイルを使用することで、ブラウザはページをより速くレンダリングでき、LCPスコアを向上させることができます。

最新のNuxtバージョンではSSRレンダリング中にスタイルをインライン化しますが、entry.<hash>.cssスタイルシートは引き続きHTMLでレンダリングされます。これはレンダリングをブロックするCSSにつながり、最大コンテンツの描画スコアに悪影響を及ぼす可能性があります。

なぜそうなるのでしょうか?Nuxtコアチームメンバーの@danielroeによる説明によると

これは現在のインラインスタイル実装の限界だと思います。

アプリの*あらゆる場所*で使用されているスタイルは、CSSソースから直接完全に安全に削除できます。しかし、1つのコンポーネントまたはページでのみ使用されているCSSは、CSSファイルに*も*インライン化されて配置される必要があります。

現時点では、ViteがクライアントサイドでのCSSの読み込みを完全に担当しているため、どのCSSが既に読み込まれているかを追跡したとしても、Viteが重複したCSSを含むCSSファイルを読み込むのを止めることはできません。

これは間違いなく修正したい点です。

まず、メインアプリケーションのスタイルをapp.vueファイルにインポートしてみてください。これらはNuxtがビルドされるときにentryCSSファイルとして保存されます。

// `app.vue`
import '~/assets/css/main.css'

次に、disableStylesheetsオプションをentryに設定して、entry.<hash>.cssスタイルシートがHTMLでレンダリングされないようにします。

// `nuxt.config.ts`
export default defineNuxtConfig({
  modules: ['nuxt-vitalizer'],

  vitalizer: {
    disableStylesheets: 'entry'
  }
})

モジュールオプション

interface ModuleOptions {
  /**
   * Whether to remove prefetch links from the HTML. If set to `dynamicImports`, only dynamic imports will be removed. To disable all prefetching, such as images, set to `true`.
   *
   * @remarks
   * This will prevent the browser from downloading chunks that may not be needed yet. This can be useful for improving the LCP (Largest Contentful Paint) score.
   *
   * @default 'dynamicImports'
   */
  disablePrefetchLinks?: boolean | 'dynamicImports'

  /**
   * Whether to remove preload links from the HTML. This can be useful for improving the FCP (First Contentful Paint) score, especially when emulating slow network conditions.
   *
   * @default false
   */
  disablePreloadLinks?: boolean

  /**
   * Whether to remove the render-blocking stylesheets from the HTML. This only makes sense if styles are inlined during SSR rendering. To only prevent the `entry.<hash>.css` stylesheet from being rendered, set to `entry`. If set to `true`, all stylesheet links will not be rendered.
   *
   * @remarks
   * This requires to have the Nuxt `inlineStyles` feature enabled. Make sure to test your application after enabling this option.
   *
   * @default false
   */
  disableStylesheets?: boolean | 'entry'
}

💻 開発

  1. このリポジトリをクローンする
  2. corepack enable を使用して Corepack を有効にする
  3. pnpm installを使用して依存関係をインストールする
  4. pnpm run dev:prepare を実行します。
  5. pnpm run dev を使用して開発サーバーを起動します。

クレジット

  • このモジュールを着想するきっかけとなったNuxt GitHub issuesでのすべての議論と貢献。

ライセンス

MITライセンス © 2024-PRESENT Johann Schopplich