Heim >Web-Frontend >CSS-Tutorial >Ein Ansatz zum faulen Laden benutzerdefinierter Elemente
In diesem Artikel wird eine faule Lademethode für benutzerdefinierte Elemente zur Verbesserung der Webseitenleistung untersucht. Diese Methode wurde von den Experimenten der Kollegen inspiriert, und ihre Kernidee bestand darin, den entsprechenden Implementierungscode automatisch zu laden, nachdem benutzerdefinierte Elemente dem DOM hinzugefügt wurden.
Normalerweise besteht kein so komplexer fauler Lademechanismus, aber die in diesem Artikel beschriebenen Techniken sind für bestimmte Szenarien immer noch wertvoll.
Um die Konsistenz aufrechtzuerhalten, ist der faule Lader selbst auch als benutzerdefiniertes Element für eine einfache Konfiguration über HTML ausgelegt. Zunächst müssen wir ungelöste benutzerdefinierte Elemente nach und nach identifizieren:
class AutoLoader extends HTMLElement { connectedCallback() { const scope = this.parentNode; this.discover(scope); } } customElements.define("ce-autoloader", AutoLoader);
Angenommen, wir haben dieses Modul vorgeladen (idealerweise mit einer asynchronen Methode), können wir das Dokument <ce-autoloader></ce-autoloader>
Element hinzufügen. Dadurch wird der Suchprozess sofort für alle untergeordneten Elemente gestartet, die das Stammelement bilden. Durch Hinzufügen von <ce-autoloader></ce-autoloader>
zum entsprechenden Containerelement können Sie den Umfang der Suche in den Unterbaum des Dokuments einschränken und sogar mehrere Instanzen in verschiedenen Teilbäumen verwenden.
Als nächstes müssen wir die discover
-Methode (als Teil der obigen Klasse) implementieren: 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); } } }Dieser Code überprüft nach dem Stammelement und all seinen Nachkommen (*). Wenn das Element ein benutzerdefiniertes Element ist (ein beilagerter Etikett), aber noch nicht aktualisiert wurde, versuchen Sie, die entsprechende Definition zu laden. Diese Methode kann eine große Menge an DOM -Abfrageressourcen einnehmen, daher muss sie mit Vorsicht behandelt werden. Wir können die Last am Haupt -Thread reduzieren, indem wir die Ausführung verzögern:
connectedCallback() { const scope = this.parentNode; requestIdleCallback(() => { this.discover(scope); }); }
Nicht alle Browser unterstützen es, Sie können requestIdleCallback
als Sicherungsplan verwenden: requestAnimationFrame
const defer = window.requestIdleCallback || requestAnimationFrame; class AutoLoader extends HTMLElement { connectedCallback() { const scope = this.parentNode; defer(() => { this.discover(scope); }); } // ... }Jetzt können wir die
-Methode implementieren, die load
Elemente dynamisch injizieren: <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`; }Bitte beachten Sie die hartcodierte Konvention in
. In der URL des elementURL
Attributs geht davon aus, dass ein Verzeichnis, das alle benutzerdefinierten Elementdefinitionen enthält (z. B. src
→ <my-widget></my-widget>
). Wir können komplexere Strategien anwenden, aber dies reicht für unsere Zwecke. Delegieren Sie diese URL an eine separate Methode, um bei Bedarf die projektspezifische Unterklasse zu ermöglichen: /components/my-widget.js
class FancyLoader extends AutoLoader { elementURL(tag) { // 自定义逻辑 } }In beiden Fällen verlassen wir uns auf
. Dies ist die zuvor erwähnte Konfigurierbarkeit. Fügen wir einen entsprechenden Getter hinzu: 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; }Wir müssen
nicht verwenden, da die Aktualisierung der observedAttributes
-Mobilie zur Laufzeit unnötig erscheint. root-dir
. <ce-autoloader root-dir="/components"></ce-autoloader>
ins Spiel: MutationObserver
class AutoLoader extends HTMLElement { connectedCallback() { const scope = this.parentNode; this.discover(scope); } } customElements.define("ce-autoloader", AutoLoader);
Auf diese Weise benachrichtigt uns der Browser, wenn ein neues Element im DOM erscheint (genauer gesagt unser entsprechendes Subtree), und wir verwenden es dann, um den Nachschlagprozess neu zu starten.
Unser Autoloader ist jetzt vollständig verwendbar. Zukünftige Verbesserungen können die Untersuchung der potenziellen Wettbewerbsbedingungen und der Optimierung umfassen. Aber für die meisten Szenarien reicht das aus. Wenn Sie einen anderen Ansatz haben, lassen Sie es mich bitte in den Kommentaren wissen und wir können miteinander kommunizieren!
Das obige ist der detaillierte Inhalt vonEin Ansatz zum faulen Laden benutzerdefinierter Elemente. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!