コンテンツにスキップ
svelte-vitals
日本語
Esc
移動開く⌘Jプレビュー
このページの内容

ライブダッシュボード

`vite dev` 中に動作する、フィルタ可能なライブのコード健全性ダッシュボード。デフォルトで有効、ビルド不要。

@svelte-vitals/vitesvelteVitals() プラグインは、vite dev 中に /__svelte-vitals/ でライブダッシュボードを配信します。検索と並び替えができるルート一覧と選択中ルートの詳細ペイン、あるいはプロジェクト全体の指摘を集約した「Overview」で構成され、作業に合わせてその場で更新されます。デフォルトで有効です。無効化する場合は無効化するを参照してください。

import { svelteVitals } from '@svelte-vitals/vite';

export default {
  plugins: [svelteVitals() /* , sveltekit() */]
};

vite dev はサーバー起動のたびに、自身の Local:/Network: 行の直後にダッシュボードの URL を出力します。/__svelte-vitals/ というパスを覚えておく必要はありません。

  ➜  svelte-vitals: http://localhost:5173/__svelte-vitals/
svelte-vitals ライブダッシュボードの Overview ペイン。Health スコアのリング、カテゴリ別バー、重要度、ルール ID、場所、修正スニペット付きの指摘一覧が表示されている。 svelte-vitals ライブダッシュボードの Overview ペイン。Health スコアのリング、カテゴリ別バー、重要度、ルール ID、場所、修正スニペット付きの指摘一覧が表示されている。

起動直後からのプロジェクト全体カバレッジ

dev サーバーの起動直後から、ダッシュボードはプロジェクト全体を表示します。起動時に、全ルートと全カテゴリ(SEO、Performance、Correctness、Security、Architecture、Accessibility)を対象とする静的解析(npx svelte-vitals@latest と同じ解析)が非同期で走るため、ページを1つも訪問しなくても本物のプロジェクト Health が得られます。ソースファイル(src/ または static/ 配下、あるいは svelte.config.* / svelte-vitals.config.*)を保存すると、デバウンス付きの再解析が走り、ダッシュボードが自動的に更新されます。

「Overview」では、全ルートの指摘とプロジェクト全体のサイトチェックをひとつのリストにまとめて表示し、重要度やカテゴリのチップでそのリストを直接絞り込めます。各指摘にはどのルートのものかが表示され、クリックするとそのルートの詳細ペインへ直接移動します。

サイドバーの検索ボックスでは、ルートパスのほか、指摘のルール ID、タイトル、場所でもルートを絞り込めます。並び替えコントロールで一覧の順序を変更できます(既定はスコアが低い順)。ルート(または「Overview」)を選択すると詳細ペインが更新され、選択状態は URL のハッシュに反映されるため、リロードや共有リンクで同じ表示に戻れます。トップバーにはプロジェクト全体の再解析中であることを示す「Analyzing…」表示と、ダークモード切り替えボタンがあります。ダークモードの設定はブラウザごとに記憶され、未設定なら OS の設定に従います。

プロジェクト全体の解析が失敗した場合(例 サーバーのルートが SvelteKit プロジェクトでない場合)、失敗は console.warn でログに出力され、ダッシュボードはライブのみのモード(訪問したルートだけを表示)にフォールバックします。dev サーバーが壊れることはありません。

ブラウジングで精度を上げる

この静的なベースラインを土台に、アプリを実際にブラウジングすると結果の精度が上がります。src/hooks.server.tssvelteVitalsHandle フックを追加してください:

import { svelteVitalsHandle } from '@svelte-vitals/vite/hooks';
import { sequence } from '@sveltejs/kit/hooks';

export const handle = sequence(svelteVitalsHandle());

他のハンドルが既にある場合は、sequence の中に svelteVitalsHandle() を並べて配置してください。

svelteVitalsHandletransformPageChunk で各リクエストの完全にレンダリングされた HTML を観察します。投げっぱなし(fire-and-forget)で、レスポンスを変更もブロックもせず、自身のエラーを飲み込むため、開発サーバーを壊すことはありません。

訪問したルートでは、レンダリング済みの結果が同じルール ID の静的結果を置き換えます。動的な値では特にそちらのほうが真実に近いためです。ライブ層が実行するのは、ルート単体で判定できるルートスコープの SEO・Performance・Accessibility ルールです。ルート同士を比較するルール(seo/duplicate-titleseo/duplicate-description)とサイト全体のルール(seo/robots-txtseo/html-langa11y/doctype など)は 1 ページの HTML では答えられないため、静的結果のまま残ります。要素リストをハンドルが読まない設定ファイルから得る a11y/required-element も同様です。そのルートの他の静的な指摘、ルートを持たない(コンポーネント/サイト単位の)指摘、未訪問のルートはそのまま残ります。ルート見出しには由来のバッジが付きます: レンダリング層があれば measured、なければ static です。

このフックは開発時以外は何もしませんesm-envDEV フラグはビルド時に静的に解決されるため、ルールセットは構築されず、本番環境でのランタイムコストはゼロです。

svelteVitalsHandle はオプションのオブジェクトを受け付けます:

オプション 説明
metaComponents string[] 解析が追跡できないヘッドメタデータ出力コンポーネント名
rules Record<string, RuleSetting> ルールごとの上書き設定(例:{ 'seo/json-ld': 'off' }

例:

export const handle = sequence(
  svelteVitalsHandle({
    metaComponents: ['SeoHead'],
    rules: { 'seo/json-ld': 'off' }
  })
);

注意事項:

  • ハンドルが分析するのはレンダリングされた HTML だけです。<head>、本文の見出し、画像、ランドマーク、id という、ブラウザが受け取るデータと同じものです。ソースレベルの動的な値(例:{data.title})はハンドルが見る時点で常に解決されているため、treatDynamicAs はここでは適用されません。
  • ハンドルは自身のオプションだけで動き、svelte-vitals.config.* は読みません。設定ファイルに置いたルール設定・オプション・overrides は静的ベースラインには効きますが、ライブ層には効きません。必要なルール設定は上のオプションオブジェクトに書き直してください。
  • failOn は使用されません、リクエストをゲートしません。
  • ライブ更新はループバックオリジン(localhost127.0.0.1[::1])でのみ流れます。vite dev --host で LAN の IP からアプリを開いた場合、ハンドルは ingest の POST をスキップする(Host ヘッダー偽装への防御)ため、訪問したルートが measured に切り替わりません。その場合は localhost から開いてください。
  • SVELTE_VITALS_DEBUG=true を設定すると、飲み込まれた内部エラー(分析失敗、ingest のスキップ)がトラブルシューティング用にターミナルへ表示されます。

指摘ごとに修正プロンプトをコピーする

各指摘カードには、デフォルトで閉じている AI Prompt というディスクロージャーがあります。開いて Copy を押すと、お使いのコーディングエージェントにそのまま貼り付けられるプロンプトをコピーできます。プロンプトは、その指摘のルール ID、場所、推奨対応、fix、ドキュメントリンクから組み立てられます:

Fix this svelte-vitals finding:

- Rule: seo/title-presence — Missing <title> (critical)
- Route: /blog/hello
- Location: src/routes/blog/hello/+page.svelte:3
- Recommendation: Add a <title> inside <svelte:head>.
- Fix: Add a <title> tag.

```svelte
<svelte:head>
  <title>Hello</title>
</svelte:head>
```

- Docs: https://oekazuma.github.io/svelte-vitals/ja/rules/seo/title-presence

After fixing, re-run `svelte-vitals --diff` (or revisit this route) to confirm seo/title-presence passes for /blog/hello.

プロンプトの生成に AI は一切関与しません。ダッシュボードのスナップショットに既に含まれている svelte-vitals 自身のルールデータ、つまりagent レポーターが修正ドキュメントに使うのと同じフィールドから即座に組み立てるため、ルールの実際の推奨にない修正が捏造される余地はありません。

無効化する

ダッシュボードはデフォルトで有効です。ビルド時ゲートだけが必要で、dev 時のダッシュボードは不要な場合(例)は、ui: false を指定してください:

export default {
  plugins: [svelteVitals({ ui: false })]
};

バージョンのずれ

ダッシュボードのトップバーには v<@svelte-vitals/vite のバージョン> と、その隣に core v<@svelte-vitals/core のバージョン> が表示されます。CLI と検出結果を比較するとき、注目すべきは後者の core バージョンです。svelte-vitals(CLI)と @svelte-vitals/vite はそれぞれ独立してバージョン管理されつつ、共有のルールエンジンである @svelte-vitals/core をラップしているだけなので、両方のパッケージ自体は最新に見えていても、実際には異なる core バージョンに解決されることがあります。その場合、新しい core リリースで追加されたルールは、実際にそのバージョンに依存している側にしか現れません。

これはパッケージマネージャーのクールダウン/固定機能によって、気づかないうちに発生し得ます。例えば pnpm の minimumReleaseAge が有効だと、pnpm dlx svelte-vitals@latest が「十分に時間の経った」古いリリースへ静かに解決され、その CLI が使う core が、lockfile 上の @svelte-vitals/vite の依存する core より古くなることがあります。同じプロジェクトで CLI とダッシュボードの検出結果が食い違う場合は、まず svelte-vitals --version を実行して (core X.Y.Z) の部分をダッシュボードのトップバーの core vX.Y.Z と比較してください。バグを疑う前に真っ先に確認すべき点です。