通常、このような複雑な怠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>
のハードコーディングされたコンベンションに注意してください。
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);
私たちのオートローダーは現在完全に使用可能になりました。将来の強化には、潜在的な競争条件と最適化の研究が含まれる場合があります。しかし、ほとんどのシナリオでは、それで十分です。別のアプローチがある場合は、コメントでお知らせください。お互いにコミュニケーションをとることができます!
以上が怠zyなロードカスタム要素へのアプローチの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。