ما طرفدار هستیم عناصر سفارشی اطراف اینجا. طراحی آنها آنها را می سازد به ویژه در معرض بارگذاری تنبل است، که می تواند یک موهبت برای عملکرد باشد.
با الهام از یک همکار آزمایشها، من اخیراً شروع به نوشتن یک بارگذار خودکار ساده کردهام: هر زمان که یک عنصر سفارشی در DOM ظاهر میشود، اگر هنوز در دسترس نیست، میخواهیم پیادهسازی مربوطه را بارگیری کنیم. سپس مرورگر مراقب ارتقای چنین عناصری از آنجا به بعد است.
این احتمال وجود دارد که شما واقعاً به همه اینها نیاز نداشته باشید. معمولا یک رویکرد ساده تر وجود دارد. تکنیکهای نشاندادهشده در اینجا، اگر عمداً استفاده شوند، ممکن است همچنان مفیدی برای مجموعه ابزار شما باشند.
برای یکپارچگی، میخواهیم بارگذار خودکار ما نیز یک عنصر سفارشی باشد – که همچنین به این معنی است که میتوانیم آن را به راحتی از طریق HTML پیکربندی کنیم. اما ابتدا، بیایید آن عناصر سفارشی حل نشده را گام به گام شناسایی کنیم:
class AutoLoader extends HTMLElement { connectedCallback() { let scope = this.parentNode; this.discover(scope); }
}
customElements.define("ce-autoloader", AutoLoader);
با فرض اینکه ما این ماژول را از قبل بارگذاری کرده ایم (با استفاده از async
ایده آل است)، می توانیم a را رها کنیم <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
روش تزریق پویا a <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 و توزیع روابط عمومی. امروز تقویت شوید.
- پلاتوبلاک چین. Web3 Metaverse Intelligence. دانش تقویت شده دسترسی به اینجا.
- منبع: https://css-tricks.com/an-approach-to-lazy-loading-custom-elements/
- 1
- a
- درباره ما
- بالاتر
- حساب
- واقعا
- اضافه
- اضافه
- معرفی
- کم کردن
- اجازه می دهد تا
- قبلا
- و
- روش
- استدلال
- دور و بر
- در دسترس
- مرورگر
- نامزد
- نمی توان
- اهميت دادن
- دقیق
- شانس
- بررسی
- کودک
- کلاس
- بیا
- نظرات
- مقايسه كردن
- شرایط
- ظرف
- قرارداد
- متناظر
- میتوانست
- دوره
- سفارشی
- طرح
- مختلف
- کشف
- سند
- نمی کند
- DOM
- قطره
- بطور پویا
- آسان تر
- به آسانی
- دارای جزئیات - بسیط
- عناصر
- کافی
- خطا
- اتر (ETH)
- EV
- حتی
- هر
- جز
- گران
- ناموفق
- طرفداران
- نام خانوادگی
- از جانب
- کاملا
- تابعی
- آینده
- رفتن
- خوب
- سر
- اینجا کلیک نمایید
- HTML
- HTTPS
- دلخواه
- شناسایی
- بلافاصله
- انجام
- پیاده سازی
- اجرای
- in
- در عوض
- بررسی
- IT
- جاوا اسکریپت
- کار
- نوع
- دانستن
- طول
- محدود
- کوچک
- بار
- بارگیری
- نگاه کنيد
- اصلی
- ساخت
- باعث می شود
- به معنی
- روش
- قدرت
- گم
- واحد
- بیش
- اکثر
- حرکت
- موزیلا
- چندگانه
- نیاز
- ضروری
- جدید
- گره
- بخش
- کارایی
- افلاطون
- هوش داده افلاطون
- PlatoData
- بازی
- به علاوه
- پتانسیل
- شاید
- روند
- اهداف
- نژاد
- تازه
- برداشتن
- قابل احترام
- برگشت
- ریشه
- سناریوها
- حوزه
- به نظر می رسد
- جداگانه
- تنظیم
- باید
- نشان داده شده
- ساده
- تنها
- So
- چیزی
- شروع
- گام
- هنوز
- استراتژی ها
- چنین
- پشتیبانی
- TAG
- طول می کشد
- تکنیک
- La
- شان
- اشیاء
- تفکر
- به
- درست
- به روز رسانی
- به روز رسانی
- URI
- URL
- us
- استفاده کنید
- معمولا
- از طريق
- که
- اراده
- مهاجرت کاری
- با این نسخهها کار
- نوشته
- شما
- زفیرنت