私たちはのファンです カスタム要素 この辺です。 彼らのデザインは彼らを作ります 特に遅延読み込みに適している、これはパフォーマンスに恩恵をもたらす可能性があります。
触発され 同僚の 実験として、私は最近、単純な自動ローダーの作成に着手しました。カスタム要素が DOM に表示されるたびに、対応する実装がまだ利用可能でない場合は、それを読み込みたいと考えています。 その後、ブラウザはそのような要素をアップグレードすることを処理します。
これらすべてが実際には必要ない可能性があります。 通常、より簡単なアプローチがあります。 ここで紹介する手法は、意図的に使用すれば、ツールセットに追加するのに役立つ可能性があります。
一貫性を保つために、オートローダーもカスタム要素にしたいと考えています。これは、HTML を介して簡単に構成できることも意味します。 しかし、最初に、これらの未解決のカスタム要素を段階的に特定しましょう。
class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; this.discover(scope); }
}
customElements.define("ce-autoloader", AutoLoader);
このモジュールを事前にロードしたと仮定します ( async
が理想的です)、ドロップすることができます <ce-autoloader>
要素に <body>
私たちの文書の。 これにより、すべての子要素の検出プロセスがすぐに開始されます <body>
、これでルート要素が構成されます。 追加することで、ドキュメントのサブツリーに検出を制限できます <ce-autoloader>
代わりに、それぞれのコンテナ要素に — 実際、異なるサブツリーに対して複数のインスタンスを持つことさえあります。
もちろん、まだそれを実装する必要があります discover
メソッド (の一部として AutoLoader
上記のクラス):
discover(scope) { let candidates = [scope, ...scope.querySelectorAll("*")]; for(let el of candidates) { let tag = el.localName; if(tag.includes("-") && !customElements.get(tag)) { this.load(tag); } }
}
ここでは、すべての子孫とともにルート要素をチェックします (*
)。 ハイフンでつながれたタグで示されているように、それがカスタム要素であるが、まだアップグレードされていない場合、対応する定義を読み込もうとします。 この方法で DOM をクエリするとコストがかかる可能性があるため、少し注意が必要です。 この作業を延期することで、メイン スレッドの負荷を軽減できます。
connectedCallback() { let scope = this.parentNode; requestIdleCallback(() => { this.discover(scope); });
}
requestIdleCallback
まだ普遍的にサポートされていませんが、使用できます requestAnimationFrame
フォールバックとして:
let defer = window.requestIdleCallback || requestAnimationFrame; class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; defer(() => { this.discover(scope); }); } // ...
}
これで、不足している機能の実装に進むことができます load
を動的に注入するメソッド <script>
素子:
load(tag) { let el = document.createElement("script"); let res = new Promise((resolve, reject) => { el.addEventListener("load", ev => { resolve(null); }); el.addEventListener("error", ev => { reject(new Error("failed to locate custom-element definition")); }); }); el.src = this.elementURL(tag); document.head.appendChild(el); return res;
} elementURL(tag) { return `${this.rootDir}/${tag}.js`;
}
ハードコーディングされた規則に注意してください elementURL
を選択します。 src
属性の URL は、すべてのカスタム要素定義が存在するディレクトリがあることを前提としています (例: <my-widget>
→ /components/my-widget.js
)。 より精巧な戦略を考え出すこともできますが、目的にはこれで十分です。 この URL を別のメソッドに委譲すると、必要に応じてプロジェクト固有のサブクラス化が可能になります。
class FancyLoader extends AutoLoader { elementURL(tag) { // fancy logic }
}
いずれにせよ、私たちが依存していることに注意してください this.rootDir
. ここで、前述の構成可能性の出番です。対応するゲッターを追加しましょう。
get rootDir() { let uri = this.getAttribute("root-dir"); if(!uri) { throw new Error("cannot auto-load custom elements: missing `root-dir`"); } if(uri.endsWith("/")) { // remove trailing slash return uri.substring(0, uri.length - 1); } return uri;
}
あなたは考えているかもしれません observedAttributes
しかし、それで物事が簡単になるわけではありません。 プラスアップデート root-dir
実行時に必要になることは決してないように思えます。
これで、要素ディレクトリを構成できるようになり、構成する必要があります。 <ce-autoloader root-dir="/components">
.
これにより、オートローダーはその仕事をすることができます。 ただし、オートローダーの初期化時にすでに存在する要素に対しては、一度だけ機能します。 動的に追加された要素も考慮する必要があるでしょう。 そこが MutationObserver
作用します:
connectedCallback() { let scope = this.parentNode; defer(() => { this.discover(scope); }); let observer = this._observer = new MutationObserver(mutations => { for(let { addedNodes } of mutations) { for(let node of addedNodes) { defer(() => { this.discover(node); }); } } }); observer.observe(scope, { subtree: true, childList: true });
} disconnectedCallback() { this._observer.disconnect();
}
このようにして、ブラウザーは新しい要素が DOM に現れるたびに私たちに通知します。つまり、それぞれのサブツリーです。これを使用して、発見プロセスを再開します。 (ここでカスタム要素を再発明していると主張するかもしれませんが、その通りです。)
オートローダーが完全に機能するようになりました。 将来の機能強化では、潜在的な競合状態を調査し、最適化を調査する可能性があります。 しかし、ほとんどのシナリオではこれで十分です。 別のアプローチがあり、メモを比較できる場合は、コメントでお知らせください。
- SEO を活用したコンテンツと PR 配信。 今日増幅されます。
- Platoblockchain。 Web3メタバースインテリジェンス。 知識の増幅。 こちらからアクセスしてください。
- 情報源: https://css-tricks.com/an-approach-to-lazy-loading-custom-elements/
- 1
- a
- 私たちについて
- 上記の.
- 実際に
- 追加されました
- 添加
- すべて
- 緩和する
- ことができます
- 既に
- &
- アプローチ
- 主張する
- 周りに
- 利用できます
- ブラウザ
- 候補
- これ
- 注意深い
- チャンス
- チェック
- 子
- class
- 来ます
- 注釈
- 比較します
- 条件
- コンテナ
- 大会
- 対応する
- 可能性
- ここから
- カスタム
- 設計
- 異なります
- 発見
- ドキュメント
- そうではありません
- DOM
- Drop
- 動的に
- 容易
- 簡単に
- 手の込んだ
- 要素は
- 十分な
- エラー
- エーテル(ETH)
- EV
- さらに
- あらゆる
- 除く
- 高価な
- Failed:
- ファン
- 名
- から
- 完全に
- 機能的な
- 未来
- 行く
- 良い
- こちら
- HTML
- HTTPS
- 理想
- 識別する
- 直ちに
- 実装する
- 実装
- 実装
- in
- を取得する必要がある者
- 調べる
- IT
- JavaScriptを
- ジョブ
- 種類
- 知っている
- 長さ
- LIMIT
- 少し
- 負荷
- ローディング
- 見て
- メイン
- make
- 作る
- 手段
- 方法
- かもしれない
- 行方不明
- モジュール
- 他には?
- 最も
- モジラ
- の試合に
- 必要
- 必要とされる
- 新作
- 部
- パフォーマンス
- プラトン
- プラトンデータインテリジェンス
- プラトデータ
- プレイ
- さらに
- 潜在的な
- 多分
- プロセス
- 目的
- レース
- 最近
- 削除します
- それらの
- return
- ルート
- シナリオ
- スコープ
- と思われる
- 別
- セッションに
- すべき
- 示す
- 簡単な拡張で
- So
- 何か
- start
- 手順
- まだ
- 作戦
- そのような
- サポート
- TAG
- 取り
- テクニック
- アプリ環境に合わせて
- 物事
- 考え
- 〜へ
- true
- 更新
- アップグレード
- URI
- URL
- us
- つかいます
- 通常
- 、
- which
- 意志
- 仕事
- 作品
- 書き込み
- あなたの
- ゼファーネット