loading-states について
loading-statesは、アプリ全体のローディング状態と空状態を監査・実装するスキルです。待ち時間やレイアウトに応じた表示を選び、非同期処理の一覧と状態カバレッジを作成します。
主な機能
- 01非同期画面の洗い出し
- 02待ち時間とレイアウトに応じた表示選択
- 034種類の空状態の設計
- 04アクセシブルな表示パターンの実装
- 05低速ネットワークでの動作確認
活用シーン
- 01データ待ちの空白画面の改善
- 02長時間処理の進捗表示
- 03空の一覧や検索結果への状態追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sanky369/ vibe-building-skills --skill loading-statesインストール後、Claude Code で/loading-statesを入力して読み込まれたか確認します。
同梱ファイルreferences/patterns.md
詳細
読み込み中と空の状態
画面が何も表示されない、またはフリーズしたように見える状態をユーザーに決して経験させないようにしてください。アプリが待機状態になる、または空になる可能性のある箇所をすべて洗い出し、想定レイテンシに応じて適切な状態を選び、実装します。最優先の指針:インジケーターは好みではなく、待ち時間とレイアウトが既知かどうかで選びます。 単独のスピナーコンポーネントだけでなく、すべての非同期処理を網羅した監査テーブルと、実装した状態を提出してください。
使う場面/使わない場面
次の用途に使います:読み込みインジケーター、スケルトン画面、プログレスバー、空の状態(初回利用、検索結果なし、エラーによる空状態、成功による空状態)、「アプリがフリーズしたように見える」という苦情。
本当に必要なのが次の対応である場合は、代わりに引き継いでください。
- 待ち時間を短くする、または見えなくする(楽観的 UI、プリロード、キャッシュ)→
skills/frontend-design/performance-optimization— まず必ずこれを検討してください。最良の読み込み状態は、読み込み状態がないことです - 単純な再試行付き空状態を超えるエラーメッセージや復旧フロー →
skills/frontend-design/error-handling-recovery - シマー/スピナーのアニメーションの調整、タイミングトークン →
skills/frontend-design/interaction-physics
ステップ 0 — コードベースを調べ、判断できない点だけを尋ねる
- 非同期処理をすべて洗い出します。
fetch(、axios、useQuery/useSWR/createResource、isLoading/isPending/loadingフラグ、Suspense境界、ルートレベルのデータローダーを grep します。データまたはミューテーションの完了を待つビュー/コンポーネントをすべて列挙します。 - それぞれについて、待機中に現在何が表示されるかを記録します。何も表示されない(空白)、レイアウトがジャンプする、スピナー、スケルトン、または無効化されたコントロールです。「何も表示されない」と「レイアウトがジャンプする」は、最初に修正すべき不具合です。
- 既存のスケルトン/スピナー/空状態コンポーネントを確認します。重複して作るのではなく、再利用して拡張します。
- 根拠に基づいて、画面ごとの想定レイテンシを見積もります。キャッシュされたクライアント状態(ほぼ即時)、同一リージョンの API 読み取り(通常は 1 秒未満)、検索/集計エンドポイント(数秒)、アップロード/エクスポート/レポート生成(時間がかかり、測定可能なことが多い)です。既存のタイムアウト設定やテレメトリーを調べます。見積もれない場合はその旨を示し、安全策として 1 秒クラスの対応を選びます。
- 空になる可能性のあるビューをすべて列挙します。リスト、テーブル、グリッド、検索結果、受信トレイは、どれも空になる可能性があります。現在、何も表示されないままになっているものを確認します。
ユーザーへの質問は、推測できない場合に限り、まとめて一度だけ行います。長時間かかることが分かっている操作(アップロード、エクスポート、バッチジョブ)があるか、イラストや空状態に関するデザイン言語があるかを尋ねます。それ以外は前提を明示して進めます。コードから分かることについて質問して、監査を止めてはいけません。
ワークフロー
1. レイテンシの段階に応じて、各読み込み状態を選ぶ
| 想定待ち時間 | 対応 |
|---|---|
| 100ms 未満 | 何も表示しない — 一瞬だけ表示されて消えるインジケーターは、何も表示しないより悪い |
| 100ms ~ 1s | 控えめなインライン表示:ボタンのスピナー/不透明度、cursor: wait。レイアウトは変更しない |
| 1s ~ 10s | これから表示するレイアウトが既知ならスケルトン、不明ならスピナー |
| 10s 超 | プログレスバー — 測定可能なら件数/割合を示す確定進捗、測定できないなら説明テキスト付きの不確定進捗 |
分岐ルール:
- スケルトンとスピナーの使い分け: コンテンツ構造(カード、リスト、テーブル、プロフィール)が既知なら、まったく同じレイアウトを模したスケルトンを使います。構造が不明または可変の場合や、ボタンのような小さな領域にはスピナーを使います。モーダル、トースト、ドロップダウンにはスケルトンを使いません。これらは即時に表示される必要があります。
- ミューテーションと読み取りの使い分け: 送信時はボタン単位の読み込み表示(ボタン内にスピナーを表示し、ラベルを隠し、幅を維持)を使います。読み取りにはページ/セクション単位の状態を使います。局所的なミューテーションでページ全体をブロックしないでください。
- 表示のちらつき防止: 待ち時間が短い可能性がある場合は、インジケーターの表示を約 150~200ms 遅らせ、応答が速ければ何も表示されないようにします。表示を開始したら、ちらつかないよう 300~500ms 以上表示を維持します。
- 合計サイズ/件数が分かる場合は、確定進捗を不確定進捗より優先します(アップロード:バイト数、バッチ:完了したアイテム数)。
2. 空の状態は種類ごとに設計する
空のビューには、次の4種類の処理を適用します。分類してから実装してください。
| 種類 | 条件 | 必須の内容 |
|---|---|---|
| 初回利用 | ユーザーにデータがまだない | この領域の用途と、最初の項目を作成するための主要な CTA |
| 検索結果なし | 検索やフィルターに一致する結果がない | 検索内容の表示と、解除方法(「フィルターをクリア」) |
| エラーによる空状態 | 読み込みに失敗した | 平易な失敗理由と再試行アクション(複雑な復旧は skills/frontend-design/error-handling-recovery に委ねる) |
| 成功による空状態 | すべての項目が完了した(受信トレイが空) | 肯定的な確認。CTA は不要 |
ルール:アクションのない空の状態は行き止まりです。CTA を省略できるのは、成功による空状態だけです。
3. 構造上のルールに沿って実装する
- スケルトンの寸法は実際のコンテンツの寸法に合わせ、切り替え時にレイアウトがずれないようにします(これも CLS 対策です)。スペースを確保し、テキスト行の幅に変化をつけます。
- アクション時(またはフラッシュ防止の遅延後)に、すぐ読み込み状態を表示します。最初のバイトを待ってはいけません。
- アクセシビリティ:読み込み領域には
aria-busy="true"と、「読み込み中」と通知する polite live region を設定します。スケルトンにはaria-hidden="true"を設定します。プログレスバーにはrole="progressbar"とaria-valuenow/min/maxを設定します。prefers-reduced-motionが指定されている場合はシマーを停止します。 - 標準的な実装(スケルトンのシマー、ボタンのスピナー、確定的/不確定的なプログレス、4種類すべての空状態、アクセシビリティ対応ブロック)は
references/patterns.mdにあります。コードを書く際に参照してください。
4. 検証する
低速ネットワーク(DevTools のスロットリング、または意図的な遅延)をシミュレートし、空白のフレームが表示されないこと、コンテンツ切り替え時にレイアウトがずれないこと、高速な応答でインジケーターが一瞬だけ表示されないこと、空の状態にアクションが表示されることを確認します。
必須の出力形式
次の2つを納品してください。
1. コード — スケルトン/スピナー/プログレス/空状態のコンポーネントを実装し、既存のプロジェクトコンポーネントとトークンを再利用しながら、各非同期処理箇所に組み込みます。
2. 読み込みと空の状態の監査(Markdown):
## Async surface inventory
| Surface | Wait class | Current | Correct state | Status |
| Product grid | 1–10s (search API) | blank screen | card skeleton ×8 | implemented |
| Save button | 100ms–1s | none | inline button spinner | implemented |
| CSV export | >10s | spinner | determinate progress + count | implemented |
| Comments | unknown → assume 1s class | layout jump | skeleton, space reserved | implemented |
## Empty state coverage
| View | First use | No results | Error-empty | Success-empty |
| Projects list | ✓ CTA "Create project" | n/a | ✓ Retry | n/a |
| Search page | n/a | ✓ "Clear filters" | ✓ Retry | n/a |
## Assumptions
[Latency estimates you could not verify, flagged for the user]
品質基準(納品前に確認)
- インベントリ内のすべての非同期処理箇所に状態が割り当てられている。空欄を残さない
- それぞれの状態の選択が、好みではなくレイテンシの段階に基づいて説明されている
- スケルトンが実際のコンテンツのレイアウトを反映している。コンテンツ切り替え時のレイアウトシフトがない
- モーダル/トースト/ドロップダウンにスケルトンを使わない。局所的な変更にページ全体をブロックしない
- 待ち時間が短い可能性のある箇所では、インジケーターの一瞬だけの表示を防止している(表示遅延、最小表示時間)
- 成功による空状態を除くすべての空の状態にアクションがある
-
aria-busy、ライブリージョンによる通知、role="progressbar"の値、aria-hiddenのスケルトン、動きを減らす設定への対応がすべて実装されている - 10秒を超える操作では、スピナーだけでなく、進捗または説明テキストを表示する
厳禁事項:あらゆる状況でスピナーを使うこと、実データに基づかない時間の見積もり(「約2分」など)をユーザーに表示すること、即座に完了する操作に読み込み状態を表示すること。
連携
skills/frontend-design/performance-optimization→ 最初に、または並行して実行します。楽観的 UI により、多くの読み込み状態が不要になります。また、スケルトン用のスペース確保は CLS 対策と共通です。skills/frontend-design/error-handling-recovery← エラーによる空状態の配置を引き継ぎ、完全な復旧フローへと拡張します。skills/frontend-design/interaction-physics→ シマー/スピナーのアニメーションタイミングと、動きを減らす設定の基準を提供します。skills/frontend-design/component-architecture→ スケルトンが反映すべきコンポーネントの一覧を提供します。Skeleton/EmptyState を共通コンポーネントとして追加してください。
参考資料
references/patterns.md— スケルトンの構成要素とカードの例、スピナーとボタン読み込み時の CSS、確定的/不確定的なプログレスバー、4種類すべての空状態のマークアップ、アクセシビリティ対応ブロックを網羅した実装例です。コードを書く際に参照してください。