בקודלאב הזה משפרים את הביצועים של דף האינטרנט הבא באמצעות טעינת נתונים מראש (preload) של כמה משאבים ושליפה מראש (prefetch) שלהם:
מדידה
קודם כול, כדאי למדוד את ביצועי האתר לפני שמוסיפים אופטימיזציות.
- כדי לראות תצוגה מקדימה של האתר, מקישים על הצגת האפליקציה. לאחר מכן מקישים על מסך מלא .
מריצים את ביקורת הביצועים של Lighthouse (Lighthouse > Options > Performance) בגרסה הפעילה של Glitch (ראו גם זיהוי הזדמנויות לשיפור הביצועים באמצעות Lighthouse).
מערכת Lighthouse מציגה את הביקורת שנכשלה הבאה לגבי משאב שאוחזר באיחור:
- מקישים על Control+Shift+J (או על Command+Option+J ב-Mac) כדי לפתוח את DevTools.
- לוחצים על הכרטיסייה רשתות.
קובץ main.css
לא מאוחזר על ידי אלמנט קישור (<link>
) שמופיע במסמך ה-HTML, אלא על ידי קובץ JavaScript נפרד, fetch-css.js
, שמצרף את אלמנט הקישור ל-DOM אחרי האירוע window.onLoad
. כלומר, האחזור של הקובץ מתבצע רק אחרי שהדפדפן מסיים לנתח ולבצע את קובץ ה-JS. באופן דומה, אחזור של פונט אינטרנט (K2D.woff2
) שצוין ב-main.css
מתבצע רק אחרי שההורדה של קובץ ה-CSS מסתיימת.
שרשרת הבקשה הקריטית מייצגת את סדר המשאבים שהדפדפן נותן להם עדיפות ומאחזר אותם. דף האינטרנט הזה נראה כרגע כך:
├─┬ / (initial HTML file)
└── fetch-css.js
└── main.css
└── K2D.woff2
מכיוון שקובץ ה-CSS נמצא ברמה השלישית של שרשרת הבקשות, מערכת Lighthouse זיהתה אותו כמשאב שהתגלה מאוחר.
טעינה מוקדמת של משאבים קריטיים
קובץ main.css
הוא נכס קריטי שנחוץ מיד אחרי הטעינה של הדף. לגבי קבצים חשובים כמו המשאב הזה, שמתבצע אחזור שלהם בשלב מאוחר באפליקציה, מוסיפים אלמנט Link לחלק העליון של המסמך כדי להודיע לדפדפן להוריד אותו מוקדם יותר באמצעות תג של טעינה מראש של קישור.
מוסיפים תג טעינה מראש לאפליקציה הזו:
<head>
<!-- ... -->
<link rel="preload" href="main.css" as="style">
</head>
המאפיין as
משמש לזיהוי סוג המשאב שאוחזר, והמאפיין as="style"
משמש לטעינת קבצים של גיליונות סגנונות לפני השימוש בהם.
טוענים מחדש את האפליקציה ומעיינים בחלונית Network (רשת) בכלי הפיתוח.
שימו לב שהדפדפן מאחזר את קובץ ה-CSS עוד לפני שהניתוח של ה-JavaScript שאחראי על האחזור שלו מסתיים. כשמשתמשים בטעינה מראש, הדפדפן יודע לבצע אחזור מראש של המשאב מתוך הנחה שהוא חיוני לדף האינטרנט.
אם לא משתמשים בה בצורה נכונה, טעינת הנתונים מראש עלולה להזיק לביצועים על ידי שליחת בקשות מיותרות למשאבים שלא נמצאים בשימוש. באפליקציה הזו, details.css
הוא קובץ CSS נוסף שנמצא ברמה הבסיסית של הפרויקט, אבל משמש ל-/details route
נפרד. כדי להראות דוגמה לשימוש שגוי בטעינה מראש, נוסיף גם למשאב הזה רמז לטעינה מראש.
<head>
<!-- ... -->
<link rel="preload" href="main.css" as="style">
<link rel="preload" href="details.css" as="style">
</head>
טוענים מחדש את האפליקציה ומעיינים בחלונית Network.
נשלחת בקשה לאחזור details.css
, למרות שדף האינטרנט לא משתמש בו.
אם הדף לא משתמש במשאב שנטען מראש תוך כמה שניות אחרי שהוא נטען, מוצגת ב-Chrome אזהרה בחלונית מסוף.
אפשר להשתמש באזהרה הזו כדי לזהות אם יש לכם משאבים טעונים מראש שלא נמצאים בשימוש מיידי בדף האינטרנט. עכשיו אפשר להסיר את הקישור הלא הכרחי לטעינת האתר מראש בדף הזה.
<head>
<!-- ... -->
<link rel="preload" href="main.css" as="style">
<link rel="preload" href="details.css" as="style">
</head>
רשימה של כל סוגי המשאבים שאפשר לאחזר, יחד עם הערכים הנכונים שצריך להשתמש בהם למאפיין as
, מופיעה במאמר של MDN בנושא טעינת נתונים מראש.
אחזור מראש של משאבים עתידיים
אחזור מראש הוא עוד רמז לדפדפן שאפשר להשתמש בו כדי לשלוח בקשה לנכס שמשמש למסלול ניווט אחר, אבל בעדיפות נמוכה יותר מנכסים חשובים אחרים שנדרשים לדף הנוכחי.
באתר הזה, לחיצה על התמונה מעבירה אתכם למסלול details/
נפרד.
קובץ CSS נפרד, details.css
, מכיל את כל הסגנונות הנדרשים לדף הפשוט הזה. כדי לבצע אחסון מראש של המשאב הזה, מוסיפים רכיב קישור אל index.html
.
<head>
<!-- ... -->
<link rel="prefetch" href="details.css">
</head>
כדי להבין איך הפעולה הזו מפעילה בקשה לקובץ, פותחים את החלונית Network ב-DevTools ומבטלים את הסימון של האפשרות Disable cache.
מעלים מחדש את האפליקציה ומבחינים בבקשה בעדיפות נמוכה מאוד שנשלחת עבור details.css
אחרי שאחזור כל שאר הקבצים הושלם.
כשכלי הפיתוח פתוחים, לוחצים על התמונה באתר כדי לנווט לדף details
.
מאחר שרכיב קישור משמש ב-details.html
כדי לאחזר את details.css
, נשלחת בקשה למשאב כצפוי.
לוחצים על בקשת הרשת details.css
ב-DevTools כדי להציג את הפרטים שלה. תוכלו לראות שהקובץ אוחזר ממטמון האחסון של הדפדפן.
בעזרת זמן ההשבתה של הדפדפן, המערכת מבצעת בקשה מוקדמת למשאב שנחוץ לדף אחר. כך אפשר לזרז בקשות ניווט עתידיות, כי הדפדפן שומר את הנכס במטמון מוקדם יותר ומציג אותו מהמטמון לפי הצורך.
טעינה מראש ושליפה מראש (prefetch) באמצעות webpack
במאמר צמצום עומסי הנתונים של JavaScript באמצעות פיצול קוד מוסבר איך משתמשים בייבוא דינמי כדי לפצל חבילה לכמה קטעים. כדי להמחיש את זה, נשתמש באפליקציה פשוטה שמייבאת באופן דינמי מודול מ-Lodash כששולחים טופס.
אפשר לגשת לדיווח על הבאג באפליקציה הזו כאן.
קטע הקוד הבא, שנמצא ב-src/index.js,
, אחראי על ייבוא הדינמי של השיטה כשלוחצים על הלחצן.
form.addEventListener("submit", e => {
e.preventDefault()
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
פיצול חבילה משפרת את זמני הטעינה של הדפים על ידי צמצום הגודל הראשוני שלה. גרסה 4.6.0 של webpack מספקת תמיכה לטעינת קטעים מראש או לטעינת קטעים מראש (prefetch) שיובאו באופן דינמי. לדוגמה, באפליקציה הזו אפשר לאחזר מראש את השיטה lodash
בזמן שהדפדפן לא פעיל. כך, כשהמשתמש לוחץ על הלחצן, אין עיכוב באחזור המשאב.
משתמשים בפרמטר התגובה הספציפי webpackPrefetch
בתוך ייבוא דינמי כדי לבצע אחזור מראש של מקטע ספציפי.
כך זה נראה באפליקציה הזו.
form.addEventListener("submit", e => {
e.preventDefault()
import(/* webpackPrefetch: true */ 'lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
אחרי הטעינה מחדש של האפליקציה, webpack מזין תג prefetch של המשאב בחלק העליון של המסמך. אפשר לראות את זה בחלונית Elements ב-DevTools.
אם בודקים את הבקשות בחלונית Network, רואים גם שהקטע הזה מאוחזר בעדיפות נמוכה אחרי שכל שאר המשאבים נשלחו בבקשה.
אמנם prefetch הגיוני יותר בתרחיש לדוגמה הזה, אבל webpack תומך גם בעומס מראש של קטעי קוד שיובאו באופן דינמי.
import(/* webpackPreload: true */ 'module')
סיכום
בסיום הקודלאב הזה, תוכלו להבין איך טעינת נכסים מסוימים מראש או טעינת נכסים מראש לפני הבקשה יכולות לשפר את חוויית המשתמש באתר. חשוב לציין שאין להשתמש בשיטות האלה בכל משאב, ושימוש שגוי בהן עלול לפגוע בביצועים. כדי לקבל את התוצאות הטובות ביותר, מומלץ לבצע טעינת נתונים מראש או טעינת נתונים מראש באופן סלקטיבי בלבד.
לסיכום:
- כדאי להשתמש בטעינה מראש למשאבים שמתגלים בשלב מאוחר אבל הם קריטיים לדף הנוכחי.
- משתמשים באחזור מראש למשאבים שנדרשים למסלול ניווט עתידי או לפעולה של משתמש.
בשלב הזה, לא כל הדפדפנים תומכים גם בטעינה מראש וגם בטעינה מראש מבוססת-בקשה. כלומר, יכול להיות שלא כל המשתמשים באפליקציה יבחינו בשיפורים בביצועים.
למידע נוסף על האופן שבו טעינת נתונים מראש וטעינת נתונים מראש (prefetching) יכולים להשפיע על דף האינטרנט, אפשר לעיין במאמרים הבאים: