Mi rajongói vagyunk Egyedi elemek errefelé. A kialakításuk teszi őket különösen alkalmas a lusta rakodásra, ami jótékony hatással lehet a teljesítményre.
Ihlette egy kollégáé kísérletek során, nemrégiben egy egyszerű automatikus betöltő írásába fogtam: Amikor egy egyéni elem megjelenik a DOM-ban, be akarjuk tölteni a megfelelő implementációt, ha még nem elérhető. A böngésző ezután gondoskodik az ilyen elemek frissítéséről.
Valószínű, hogy valójában nem lesz szüksége mindezekre; általában van egy egyszerűbb megközelítés. Szándékosan alkalmazva az itt bemutatott technikák továbbra is hasznos kiegészítői lehetnek eszközkészletének.
A következetesség érdekében azt szeretnénk, hogy az automatikus betöltőnk is egyéni elem legyen – ami azt is jelenti, hogy könnyen konfigurálhatjuk HTML-en keresztül. De először lépésről lépésre azonosítsuk azokat a feloldatlan egyéni elemeket:
class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; this.discover(scope); }
}
customElements.define("ce-autoloader", AutoLoader);
Feltéve, hogy ezt a modult előre betöltöttük (a async
ideális), eldobhatjuk a <ce-autoloader>
elemet a <body>
dokumentumunkból. Ez azonnal elindítja a felderítési folyamatot az összes gyermek elemhez <body>
, amely most a gyökérelemünk. Hozzáadásával korlátozhatjuk a felfedezést a dokumentumunk egy részfájára <ce-autoloader>
helyette a megfelelő tárolóelemhez – sőt, akár több példányunk is lehet a különböző részfákhoz.
Természetesen ezt még végre kell hajtanunk discover
módszer (a AutoLoader
fenti osztály):
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); } }
}
Itt ellenőrizzük a gyökérelemünket és minden egyes leszármazottat (*
). Ha ez egy egyéni elem – amint azt a kötőjeles címkék jelzik –, de még nincs frissítve, akkor megpróbáljuk betölteni a megfelelő definíciót. A DOM ilyen módon történő lekérdezése költséges lehet, ezért egy kicsit óvatosnak kell lennünk. A munka elhalasztásával enyhíthetjük a főszál terhelését:
connectedCallback() { let scope = this.parentNode; requestIdleCallback(() => { this.discover(scope); });
}
requestIdleCallback
még nem támogatott általánosan, de használhatjuk requestAnimationFrame
tartalékként:
let defer = window.requestIdleCallback || requestAnimationFrame; class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; defer(() => { this.discover(scope); }); } // ...
}
Most áttérhetünk a hiányzó megvalósítására load
módszer a dinamikus injekció beadására a <script>
elem:
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`;
}
Jegyezze meg a kódolt konvenciót elementURL
Az src
attribútum URL-je feltételezi, hogy van egy könyvtár, ahol az összes egyéni elem definíció található (pl <my-widget>
→ /components/my-widget.js
). Kidolgozhatnánk kidolgozottabb stratégiákat is, de ez elég jó a céljainknak. Ennek az URL-nek egy külön metódusba való visszahelyezése lehetővé teszi a projekt-specifikus alosztályozást, ha szükséges:
class FancyLoader extends AutoLoader { elementURL(tag) { // fancy logic }
}
Akárhogy is, vegye figyelembe, hogy támaszkodunk this.rootDir
. Itt jön be a fent említett konfigurálhatóság. Adjunk hozzá egy megfelelő gettert:
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;
}
Lehet, hogy arra gondolsz observedAttributes
most, de ez nem igazán könnyíti meg a dolgokat. Plusz frissítés root-dir
futásidőben olyannak tűnik, amire soha nem lesz szükségünk.
Most már beállíthatjuk – és muszáj – beállítani az elemek könyvtárunkat: <ce-autoloader root-dir="/components">
.
Ezzel az automata rakodónk elvégezheti a dolgát. Kivéve, hogy csak egyszer működik, olyan elemeknél, amelyek már léteznek az automatikus betöltő inicializálásakor. Valószínűleg figyelembe kell venni a dinamikusan hozzáadott elemeket is. Ahol MutationObserver
játékba lép:
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();
}
Ily módon a böngésző értesít minket, ha új elem jelenik meg a DOM-ban – vagy inkább a megfelelő részfánkban –, amelyet aztán a felderítési folyamat újraindítására használunk. (Azért vitatkozhat, hogy itt újra feltaláljuk az egyéni elemeket, és igaza van.)
Automatikus betöltőnk már teljesen működőképes. A jövőbeli fejlesztések megvizsgálhatják a lehetséges versenykörülményeket, és megvizsgálhatják az optimalizációkat. De jó eséllyel ez elég jó a legtöbb forgatókönyvhöz. Írd meg kommentben, ha más a megközelítésed, és össze tudjuk hasonlítani a jegyzeteket!
- SEO által támogatott tartalom és PR terjesztés. Erősödjön még ma.
- Platoblockchain. Web3 metaverzum intelligencia. Felerősített tudás. Hozzáférés itt.
- Forrás: https://css-tricks.com/an-approach-to-lazy-loading-custom-elements/
- 1
- a
- Rólunk
- felett
- Fiók
- tulajdonképpen
- hozzáadott
- mellett
- Minden termék
- enyhít
- lehetővé teszi, hogy
- már
- és a
- megközelítés
- érvel
- körül
- elérhető
- böngésző
- jelöltek
- nem tud
- ami
- óvatos
- esély
- ellenőrizze
- gyermek
- osztály
- hogyan
- Hozzászólások
- összehasonlítani
- Körülmények
- Konténer
- Konvenció
- Megfelelő
- tudott
- tanfolyam
- szokás
- Design
- különböző
- felfedezés
- dokumentum
- Nem
- DOM
- Csepp
- dinamikusan
- könnyebb
- könnyen
- Bonyolult
- elemek
- elég
- hiba
- Eter (ETH)
- EV
- Még
- Minden
- Kivéve
- drága
- Sikertelen
- rajongók
- vezetéknév
- ból ből
- teljesen
- funkcionális
- jövő
- megy
- jó
- fej
- itt
- HTML
- HTTPS
- ideális
- azonosítani
- azonnal
- végre
- végrehajtás
- végrehajtási
- in
- helyette
- vizsgálja
- IT
- JavaScript
- Munka
- Kedves
- Ismer
- Hossz
- LIMIT
- kis
- kiszámításának
- betöltés
- néz
- Fő
- csinál
- KÉSZÍT
- eszközök
- módszer
- esetleg
- hiányzó
- modul
- több
- a legtöbb
- mozog
- Mozilla
- többszörös
- Szükség
- szükséges
- Új
- csomópont
- rész
- teljesítmény
- Plató
- Platón adatintelligencia
- PlatoData
- játszani
- plusz
- potenciális
- valószínűleg
- folyamat
- célokra
- Futam
- nemrég
- eltávolítása
- azok
- visszatérés
- gyökér
- forgatókönyvek
- hatálya
- Úgy tűnik,
- különálló
- készlet
- kellene
- mutatott
- Egyszerű
- egyetlen
- So
- valami
- kezdet
- Lépés
- Még mindig
- stratégiák
- ilyen
- Támogatott
- TAG
- tart
- technikák
- A
- azok
- dolgok
- Gondolkodás
- nak nek
- igaz
- frissítése
- frissített
- URI
- URL
- us
- használ
- rendszerint
- keresztül
- ami
- lesz
- Munka
- művek
- írás
- A te
- zephyrnet