Smo oboževalci Elementi po meri nekje tukaj. Njihova zasnova jih naredi posebej dovzetni za leno nalaganje, kar je lahko dobro za uspešnost.
Navdih kolega eksperimentov, sem se pred kratkim lotil pisanja preprostega samodejnega nalagalnika: kadar koli se v DOM pojavi element po meri, želimo naložiti ustrezno izvedbo, če še ni na voljo. Brskalnik nato poskrbi za nadgradnjo takih elementov od tam naprej.
Verjetno vsega tega dejansko ne boste potrebovali; običajno obstaja enostavnejši pristop. Tukaj prikazane tehnike so lahko uporaben dodatek k vašemu naboru orodij.
Zaradi doslednosti želimo, da je tudi naš samodejni nalagalnik element po meri – kar tudi pomeni, da ga lahko preprosto konfiguriramo prek HTML-ja. Najprej pa identificirajmo tiste nerazrešene elemente po meri, korak za korakom:
class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; this.discover(scope); }
}
customElements.define("ce-autoloader", AutoLoader);
Ob predpostavki, da smo ta modul naložili vnaprej (z uporabo async
je idealno), lahko spustimo a <ce-autoloader>
element v <body>
našega dokumenta. To bo takoj začelo postopek odkrivanja za vse podrejene elemente <body>
, ki zdaj predstavlja naš korenski element. Odkrivanje lahko omejimo na poddrevo našega dokumenta z dodajanjem <ce-autoloader>
na ustrezen vsebniški element namesto tega - dejansko lahko imamo celo več primerkov za različna poddrevesa.
Seveda moramo to še izvajati discover
metoda (kot del AutoLoader
razred zgoraj):
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); } }
}
Tukaj preverimo naš korenski element skupaj z vsakim posameznim potomcem (*
). Če gre za element po meri – kot je označeno z oznakami z vezaji – vendar še ni nadgrajen, bomo poskušali naložiti ustrezno definicijo. Poizvedovanje po DOM na ta način je lahko drago, zato moramo biti nekoliko previdni. Obremenitev glavne niti lahko zmanjšamo tako, da to delo odložimo:
connectedCallback() { let scope = this.parentNode; requestIdleCallback(() => { this.discover(scope); });
}
requestIdleCallback
še ni univerzalno podprt, vendar ga lahko uporabljamo requestAnimationFrame
kot rezerva:
let defer = window.requestIdleCallback || requestAnimationFrame; class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; defer(() => { this.discover(scope); }); } // ...
}
Zdaj lahko nadaljujemo z izvajanjem manjkajočega load
metoda za dinamično vbrizgavanje a <script>
Element:
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`;
}
Upoštevajte trdo kodirano konvencijo v elementURL
. src
URL atributa predpostavlja, da obstaja imenik, kjer se nahajajo vse definicije elementov po meri (npr <my-widget>
→ /components/my-widget.js
). Lahko bi pripravili bolj dodelane strategije, vendar je to dovolj dobro za naše namene. Prenos tega URL-ja na ločeno metodo omogoča podrazred, specifičen za projekt, kadar je to potrebno:
class FancyLoader extends AutoLoader { elementURL(tag) { // fancy logic }
}
Kakor koli že, upoštevajte, da se zanašamo na this.rootDir
. Tukaj nastopi zgoraj omenjena konfiguracija. Dodajmo ustrezen pridobivalnik:
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;
}
Morda razmišljate o observedAttributes
zdaj, vendar to v resnici ne olajša stvari. Plus posodabljanje root-dir
med izvajanjem se zdi kot nekaj, česar ne bomo nikoli potrebovali.
Zdaj lahko — in moramo — konfigurirati naš imenik elementov: <ce-autoloader root-dir="/components">
.
S tem lahko naš samodejni nakladalnik opravi svoje delo. Le da deluje samo enkrat, za elemente, ki že obstajajo, ko je samodejni nalagalnik inicializiran. Verjetno bomo želeli upoštevati tudi dinamično dodane elemente. To je kje MutationObserver
pride v poštev:
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();
}
Na ta način nas brskalnik obvesti, ko se pojavi nov element v DOM - ali bolje rečeno, našem ustreznem poddrevesu -, ki ga nato uporabimo za ponovni zagon postopka odkrivanja. (Morda bi trdili, da tukaj na novo izumljamo elemente po meri, in nekako bi imeli prav.)
Naš samodejni nakladalnik je zdaj popolnoma funkcionalen. Prihodnje izboljšave bodo morda preučile morebitne dirkalne pogoje in raziskale optimizacije. Toda verjetno je to dovolj dobro za večino scenarijev. Povejte mi v komentarjih, če imate drugačen pristop, in lahko primerjamo zapiske!
- Distribucija vsebine in PR s pomočjo SEO. Okrepite se še danes.
- Platoblockchain. Web3 Metaverse Intelligence. Razširjeno znanje. Dostopite tukaj.
- vir: https://css-tricks.com/an-approach-to-lazy-loading-custom-elements/
- 1
- a
- O meni
- nad
- Račun
- dejansko
- dodano
- Poleg tega
- vsi
- ublažiti
- omogoča
- že
- in
- pristop
- trdijo
- okoli
- Na voljo
- brskalnik
- kandidati
- ne more
- ki
- previdni
- kvote
- preveriti
- otrok
- razred
- kako
- komentarji
- primerjate
- Pogoji
- Posoda
- Konvencija
- Ustrezno
- bi
- Tečaj
- po meri
- Oblikovanje
- drugačen
- Odkritje
- dokument
- Ne
- DOM
- Drop
- dinamično
- lažje
- enostavno
- Izdelati
- elementi
- dovolj
- Napaka
- Eter (ETH)
- EV
- Tudi
- Tudi vsak
- Razen
- drago
- ni uspelo
- ventilatorji
- prva
- iz
- v celoti
- funkcionalno
- Prihodnost
- dogaja
- dobro
- Glava
- tukaj
- HTML
- HTTPS
- idealen
- identificirati
- takoj
- izvajati
- Izvajanje
- izvajanja
- in
- Namesto
- razišče
- IT
- JavaScript
- Job
- Otrok
- Vedite
- dolžina
- LIMIT
- malo
- obremenitev
- nalaganje
- Poglej
- Glavne
- Znamka
- IZDELA
- pomeni
- Metoda
- morda
- manjka
- modul
- več
- Najbolj
- premikanje
- Mozilla
- več
- Nimate
- potrebna
- Novo
- Vozel
- del
- performance
- platon
- Platonova podatkovna inteligenca
- PlatoData
- Predvajaj
- plus
- potencial
- verjetno
- Postopek
- namene
- Dirka
- Pred kratkim
- odstrani
- tisti,
- vrnitev
- koren
- scenariji
- Obseg
- Zdi se,
- ločena
- nastavite
- shouldnt
- pokazale
- Enostavno
- sam
- So
- Nekaj
- Začetek
- Korak
- Še vedno
- strategije
- taka
- Podprti
- TAG
- meni
- tehnike
- O
- njihove
- stvari
- Razmišljanje
- do
- Res
- posodabljanje
- nadgrajen
- URI
- URL
- us
- uporaba
- navadno
- preko
- ki
- bo
- delo
- deluje
- pisanje
- Vaša rutina za
- zefirnet