ホームページ > ウェブフロントエンド > CSSチュートリアル > 怠zyなロードカスタム要素へのアプローチ

怠zyなロードカスタム要素へのアプローチ

Joseph Gordon-Levitt
リリース: 2025-03-09 11:39:10
オリジナル
216 人が閲覧しました

An Approach to Lazy Loading Custom Elements

この記事では、Webページのパフォーマンスを向上させるためのカスタム要素の怠zyな読み込み方法について説明します。この方法は、同僚の実験に触発され、その中心的なアイデアは、カスタム要素がDOMに追加された後、対応する実装コードを自動的にロードすることでした。

通常、このような複雑な怠zyなロードメカニズムは必要ありませんが、この記事で説明する手法は、特定のシナリオにとって依然として価値があります。

一貫性を維持するために、Lazy Loader自体は、HTMLを介して簡単な構成のためのカスタム要素として設計されています。まず、未解決のカスタム要素を徐々に識別する必要があります:

このモジュールをプリロードしたと仮定すると(理想的には非同期メソッドを使用しています)、

要素をドキュメントに追加できます。これにより、ルート要素を形成するすべての子要素の検索プロセスがすぐに開始されます。対応するコンテナ要素に
class AutoLoader extends HTMLElement {
  connectedCallback() {
    const scope = this.parentNode;
    this.discover(scope);
  }
}
customElements.define("ce-autoloader", AutoLoader);
ログイン後にコピー
ログイン後にコピー
を追加することにより、ルックアップの範囲をドキュメントのサブツリーに制限し、異なるサブツリーで複数のインスタンスを使用することもできます。

<ce-autoloader></ce-autoloader>次に、<ce-autoloader></ce-autoloader>メソッドを実装する必要があります(上記のクラスの一部として):

discoverこのコードは、ルート要素とそのすべての子孫(*)をチェックします。要素がカスタム要素(ハイフン化ラベル)であるが、まだアップグレードされていない場合は、対応する定義をロードしてみてください。この方法は、大量のDOMクエリリソースを占有する可能性があるため、注意して処理する必要があります。実行を遅らせることにより、メインスレッドの負荷を減らすことができます:AutoLoader

discover(scope) {
  const candidates = [scope, ...scope.querySelectorAll("*")];
  for (const el of candidates) {
    const tag = el.localName;
    if (tag.includes("-") && !customElements.get(tag)) {
      this.load(tag);
    }
  }
}
ログイン後にコピー

すべてのブラウザがそれをサポートしているわけではありません。バックアッププランとして

を使用できます:
connectedCallback() {
  const scope = this.parentNode;
  requestIdleCallback(() => {
    this.discover(scope);
  });
}
ログイン後にコピー

requestIdleCallbackここで、requestAnimationFrameメソッドを実装し、

要素を動的に挿入できます:
const defer = window.requestIdleCallback || requestAnimationFrame;

class AutoLoader extends HTMLElement {
  connectedCallback() {
    const scope = this.parentNode;
    defer(() => {
      this.discover(scope);
    });
  }
  // ...
}
ログイン後にコピー

load <script></script>のハードコーディングされたコンベンションに注意してください。

属性のURLは、すべてのカスタム要素定義を含むディレクトリがあることを前提としています(例:
load(tag) {
  const el = document.createElement("script");
  const res = new Promise((resolve, reject) => {
    el.addEventListener("load", () => resolve(null));
    el.addEventListener("error", () => reject(new Error("未能找到自定义元素定义")));
  });
  el.src = this.elementURL(tag);
  document.head.appendChild(el);
  return res;
}

elementURL(tag) {
  return `${this.rootDir}/${tag}.js`;
}
ログイン後にコピー

)。より複雑な戦略を採用することはできますが、これは私たちの目的に十分です。このURLを別の方法に委任し、必要に応じてプロジェクト固有のサブクラス化を許可します。 elementURL どちらにしても、srcに依存しています。これは、前述の構成可能性です。対応するゲッターを追加しましょう:<my-widget></my-widget> /components/my-widget.js

class FancyLoader extends AutoLoader {
  elementURL(tag) {
    // 自定义逻辑
  }
}
ログイン後にコピー
プロパティを更新する必要はないため、使用する必要はありません。

this.rootDirさて、要素ディレクトリを構成することができます(そしてマスト)

get rootDir() {
  const uri = this.getAttribute("root-dir");
  if (!uri) {
    throw new Error("无法自动加载自定义元素:缺少`root-dir`属性");
  }
  return uri.endsWith("/") ? uri.substring(0, uri.length - 1) : uri;
}
ログイン後にコピー
これで、私たちのオートローダーは機能します。ただし、オートローダーが初期化されたときに既に存在する要素に対してのみ機能します。また、動的に追加された要素を考慮する必要がある場合があります。これは

が出てくる場所です:observedAttributes

class AutoLoader extends HTMLElement {
  connectedCallback() {
    const scope = this.parentNode;
    this.discover(scope);
  }
}
customElements.define("ce-autoloader", AutoLoader);
ログイン後にコピー
ログイン後にコピー
このように、ブラウザは、新しい要素がDOMに表示されたときに通知します(より正確には、対応するサブツリー)、それを使用してルックアッププロセスを再起動します。

私たちのオートローダーは現在完全に使用可能になりました。将来の強化には、潜在的な競争条件と最適化の研究が含まれる場合があります。しかし、ほとんどのシナリオでは、それで十分です。別のアプローチがある場合は、コメントでお知らせください。お互いにコミュニケーションをとることができます!

以上が怠zyなロードカスタム要素へのアプローチの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート