אנחנו מעריצים של אלמנטים מותאמים אישית פה באיזור. העיצוב שלהם עושה אותם מתאים במיוחד לטעינה עצלה, מה שיכול להיות ברכה לביצועים.
קיבל השראה מ של עמית ניסויים, לאחרונה התחלתי לכתוב טוען אוטומטי פשוט: בכל פעם שרכיב מותאם אישית מופיע ב-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
כתובת האתר של המאפיין מניחה שקיימת ספרייה שבה כל הגדרות הרכיבים המותאמים אישית נמצאות (למשל <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. קבל הגברה היום.
- Platoblockchain. Web3 Metaverse Intelligence. ידע מוגבר. גישה כאן.
- מקור: https://css-tricks.com/an-approach-to-lazy-loading-custom-elements/
- 1
- a
- אודות
- מֵעַל
- חֶשְׁבּוֹן
- למעשה
- הוסיף
- תוספת
- תעשיות
- להקל
- מאפשר
- כְּבָר
- ו
- גישה
- לטעון
- סביב
- זמין
- דפדפן
- מועמדים
- לא יכול
- אשר
- זהיר
- סיכויים
- לבדוק
- ילד
- בכיתה
- איך
- הערות
- לְהַשְׁווֹת
- תנאים
- מכולה
- אמנה
- תוֹאֵם
- יכול
- קורס
- מנהג
- עיצוב
- אחר
- תגלית
- מסמך
- לא
- DOM
- ירידה
- באופן דינמי
- קל יותר
- בקלות
- משוכלל
- אלמנטים
- מספיק
- שגיאה
- Ether (ETH)
- EV
- אֲפִילוּ
- כל
- אלא
- יקר
- נכשל
- מעריצים
- ראשון
- החל מ-
- לגמרי
- פונקציונלי
- עתיד
- הולך
- טוב
- ראש
- כאן
- HTML
- HTTPS
- אידאל
- לזהות
- מיד
- ליישם
- הפעלה
- יישום
- in
- במקום
- לחקור
- IT
- JavaScript
- עבודה
- סוג
- לדעת
- אורך
- להגביל
- קְצָת
- לִטעוֹן
- טוען
- נראה
- ראשי
- לעשות
- עושה
- אומר
- שיטה
- יכול
- חסר
- מודול
- יותר
- רוב
- המהלך
- מוזילה
- מספר
- צורך
- נחוץ
- חדש
- צומת
- חלק
- ביצועים
- אפלטון
- מודיעין אפלטון
- אפלטון נתונים
- לְשַׂחֵק
- ועוד
- פוטנציאל
- כנראה
- תהליך
- למטרות
- גזע
- לאחרונה
- להסיר
- אלה
- לַחֲזוֹר
- שורש
- תרחישים
- היקף
- נראה
- נפרד
- סט
- צריך
- הראה
- פָּשׁוּט
- יחיד
- So
- משהו
- התחלה
- שלב
- עוד
- אסטרטגיות
- כזה
- נתמך
- תָג
- לוקח
- טכניקות
- אל האני
- שֶׁלָהֶם
- דברים
- חושב
- ל
- נָכוֹן
- עדכון
- משודרג
- URI
- כתובת האתר
- us
- להשתמש
- בְּדֶרֶך כְּלַל
- באמצעות
- אשר
- יצטרך
- תיק עבודות
- עובד
- כתיבה
- זפירנט