`data-wa-preload` 属性でオートローダーにコンポーネントの事前読み込みを指定できるように

shoelace-style/webawesome

Web Awesome のオートローダーに data-wa-preload 属性のサポートが追加され、ページ初回表示時点で DOM に存在しないコンポーネントを事前に登録できるようになりました。これにより、動的に追加される Web Awesome コンポーネントの FOUCE(Flash of Undefined Custom Elements) を防止できます。

背景

既存のオートローダーは、ページのロード時に DOM を走査して Custom Elements を検出し、必要なコンポーネントを動的に登録する仕組みを持っています。しかし、JavaScript によってコンポーネントが動的に追加される場合、オートローダーの初回走査後に要素が挿入されるため、コンポーネントが未定義の状態で一瞬描画されてしまう問題がありました。この問題は #1501 で報告されており、ユーザーから「後から動的に追加する要素についても事前読み込みできる手段が欲しい」という要望が寄せられていました。

解決策として、HTML の属性を通じて「あらかじめロードすべきタグ名」を宣言できる仕組みが求められていました。JavaScript のコードを変更せず、マークアップ側で制御できる点が重要な設計要件となっています。

技術的な変更

autoloader.tsdiscover 関数に、data-wa-preload 属性を持つ要素を収集するロジックが追加されました。

変更は packages/webawesome/src/utilities/autoloader.tsdiscover 関数内、タグ名のユニーク化処理の直前に挿入されています。

追加されたコード:

// Collect tags from data-wa-preload attributes
const preloadSelectors = root.querySelectorAll('[data-wa-preload]');
const preloadRoots =
  root instanceof Element && root.hasAttribute('data-wa-preload') ? [root, ...preloadSelectors] : preloadSelectors;
for (const el of preloadRoots) {
  tags.push(
    ...(el as Element)
      .getAttribute('data-wa-preload')!
      .split(/\s+/)
      .filter(tag => tag.startsWith('wa-')),
  );
}

処理の流れは次のとおりです:

  1. root.querySelectorAll('[data-wa-preload]')data-wa-preload 属性を持つ全子孫要素を収集する
  2. root 自身が Element かつ data-wa-preload 属性を持つ場合は、root も収集対象に含める
  3. 各要素の属性値をスペース区切りで分割し、wa- プレフィックスを持つタグ名のみを既存の tags 配列に追加する
  4. 既存の [...new Set(tags)] によるユニーク化処理で重複が除去される

属性の値には、スペース区切りで複数のタグ名を列挙できます:

<div data-wa-preload="wa-dialog wa-drawer wa-tooltip">
  <!-- 動的に追加されるコンテンツ -->
</div>

フィルタ条件として tag.startsWith('wa-') が適用されるため、不正な文字列や空白が属性値に混入しても、wa- プレフィックスを持たないものは無視されます。

設計判断

既存の discover 関数と tags 配列への統合という方式が採用されました。新たなローディング経路を追加するのではなく、DOM 走査で収集したタグ名と同じリストに追記し、その後のユニーク化・登録処理を共有する設計です。

rootElement の場合に root 自身も対象とする条件分岐は、discoverDocument だけでなく任意の ElementShadowRoot を引数に取れる汎用的なシグネチャを持つことへの配慮です。DocumenthasAttribute を持たないため、root instanceof Element でガードしています。

また、wa- プレフィックスによるフィルタリングにより、属性値の検証を最小限のコストで行えます。専用のバリデーションロジックを設けず、既存の命名規則を利用した簡潔な実装といえます。

まとめ

data-wa-preload の追加は、HTML のマークアップで事前読み込みコンポーネントを宣言できるようにすることで、動的 UI を持つアプリケーションでの FOUCE 問題をオートローダーの既存の仕組みの延長線上で解決した変更です。コードの変更は最小限でありながら、discover 関数の汎用的なシグネチャや既存のユニーク化処理を活かした設計は、拡張への合理的なアプローチを示しています。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
ba9833eb

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→背景・技術的変更・設計判断(各論)→まとめ(結論)という理想的な3部構成が明確に適用されています。各セクションの役割も適切です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(```typescript:path/to/file.ts)や、PR・Issueへのリンク記法([#123](URL))が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

「FOUCE」「オートローダー」「Custom Elements」などの専門用語を前提としており、対象読者であるエンジニアに適した技術レベルと表現で書かれています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションの冒頭パラグラフが要旨を述べており、各段落もトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が遵守されています。非常に読みやすい構成です。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事に引用されているコードブロックは、提供されたDiffの内容と完全に一致しており、ファイルパスも正確です。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

PR情報で使われている`autoloader`や`FOUCE`といった技術用語を正確に使用しており、誤用は見られません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

コード変更の処理の流れや目的についての説明は、Diffの内容と整合性が取れており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事の主張はすべてPRのDescriptionやDiffのコード内容に基づいています。「設計判断」セクションはコードから読み取れる意図を的確に言語化しており、ハルシネーションは検出されませんでした。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#2238)や関連するIssue番号(#1501)が正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルはPRのタイトル「Add the ability to preload components via autoloader with `data-wa-preload`」の内容を正確に要約しており、主題との一致も問題ありません。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

PR情報に含まれないバージョン情報やリリース予定などの外部知識の追記はなく、提供された情報源に忠実です。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「初回走査後」「動的に追加」といった時間的な前後関係は、PRのDescriptionの内容と一致しており、正確に表現されています。