בקודלאב הזה משפרים את הביצועים של דף האינטרנט הבא באמצעות טעינת נתונים מראש (preload) של כמה משאבים ושליפה מראש (prefetch) שלהם:
מדידה
לפני שמוסיפים אופטימיזציה של האתר, צריך למדוד את ביצועי האתר.
- כדי לראות תצוגה מקדימה של האתר, לוחצים על View App (הצגת האפליקציה) ואז על Fullscreen (מסך מלא).
מריצים את ביקורת הביצועים של Lighthouse (Lighthouse > Options > Performance) בגרסה הפעילה של Glitch (ראו גם זיהוי הזדמנויות לשיפור הביצועים באמצעות Lighthouse).
מערכת Lighthouse מציגה את הביקורת שנכשלה הבאה לגבי משאב שאוחזר באיחור:
- מקישים על 'Control+Shift+J' (או על 'Command+Option+J' ב-Mac) כדי לפתוח את כלי הפיתוח.
- לוחצים על הכרטיסייה רשתות.
קובץ 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 אחר שנמצא ברמה הבסיסית (root) של הפרויקט, אבל משמש לקובץ /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 בנושא טעינת נתונים מראש.
אחזור מראש של משאבים עתידיים
שליפה מראש (prefetch) היא רמז נוסף לדפדפן שאפשר להשתמש בו כדי לשלוח בקשה לנכס שמשמש למסלול ניווט שונה, אבל בעדיפות נמוכה יותר מנכסים חשובים אחרים שנדרשים לדף הנוכחי.
באתר הזה, לחיצה על התמונה תעביר אתכם לנתיב details/
נפרד.
קובץ CSS נפרד, details.css
, מכיל את כל הסגנונות הנדרשים לדף הפשוט הזה. כדי לבצע אחסון מראש של המשאב הזה, מוסיפים רכיב קישור אל index.html
.
<head>
<!-- ... -->
<link rel="prefetch" href="details.css">
</head>
כדי להבין איך הפעולה הזו מפעילה בקשה לקובץ, פותחים את החלונית Network בכלי הפיתוח ומבטלים את הסימון של האפשרות Disable cache.
טענו מחדש את האפליקציה שימו לב שהבקשה ל-details.css
נשלחת בעדיפות נמוכה מאוד אחרי שאחזור כל שאר הקבצים.
כשכלי הפיתוח פתוחים, לוחצים על התמונה באתר כדי לנווט לדף details
.
מאחר שרכיב קישור משמש ב-details.html
כדי לאחזר את details.css
, נשלחת בקשה למשאב כצפוי.
לוחצים על בקשת הרשת details.css
ב-DevTools כדי להציג את הפרטים שלה. תוכלו לראות שהקובץ מאוחזר ממטמון הדיסק של הדפדפן.
בעזרת זמן ההשבתה של הדפדפן, המערכת מבצעת בקשה מוקדמת למשאב שנחוץ לדף אחר. כך אפשר לזרז בקשות ניווט עתידיות, כי הדפדפן שומר את הנכס במטמון מוקדם יותר ומציג אותו מהמטמון לפי הצורך.
טעינה מראש ושליפה מראש (prefetch) באמצעות webpack
במאמר צמצום עומסי הנתונים של JavaScript באמצעות פיצול קוד מוסבר איך משתמשים בייבוא דינמי כדי לפצל חבילה לכמה קטעים. כדי להמחיש את זה, נשתמש באפליקציה פשוטה שמייבאת באופן דינמי מודול מ-Lodash כששולחים טופס.
ניתן לגשת אל התקלה של האפליקציה הזו כאן.
קטע הקוד הבא, שנמצא ב-src/index.js,
, אחראי לייבוא דינמי של ה-method כשלוחצים על הלחצן.
form.addEventListener("submit", e => {
e.preventDefault()
import('lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
פיצול חבילה משפרת את זמני הטעינה של הדפים על ידי צמצום הגודל הראשוני שלה. גרסה 4.6.0 של webpack מספקת תמיכה טעינה מראש של קטעי קוד (chunks) שיובאו באופן דינמי, או טעינה מראש של קטעי קוד שמיועדים לטעינה מראש. לדוגמה, באפליקציה הזו אפשר לאחזר מראש את השיטה lodash
בזמן שהדפדפן לא פעיל. כך, כשהמשתמש לוחץ על הלחצן, אין עיכוב באחזור המשאב.
משתמשים בפרמטר התגובה הספציפי webpackPrefetch
בתוך ייבוא דינמי כדי לבצע אחזור מראש של מקטע ספציפי.
כך זה ייראה עם האפליקציה הספציפית הזו.
form.addEventListener("submit", e => {
e.preventDefault()
import(/* webpackPrefetch: true */ 'lodash.sortby')
.then(module => module.default)
.then(sortInput())
.catch(err => { alert(err) });
});
אחרי שהאפליקציה נטענת מחדש, ה-webpack מחדיר תג שליפה מראש של המשאב לראש המסמך. אפשר לראות את זה בחלונית Elements ב-DevTools.
אם בודקים את הבקשות בחלונית Network, רואים גם שהקטע הזה מאוחזר בעדיפות נמוכה אחרי שכל שאר המשאבים נדרשו.
אמנם prefetch הגיוני יותר בתרחיש לדוגמה הזה, אבל webpack תומך גם בעומס מראש של קטעי קוד שיובאו באופן דינמי.
import(/* webpackPreload: true */ 'module')
סיכום
בסיום הקודלאב הזה, תוכלו להבין איך טעינת נכסים מסוימים מראש או טעינת נכסים מראש לפני הבקשה יכולות לשפר את חוויית המשתמש באתר. חשוב לציין שאין להשתמש בשיטות האלה בכל משאב, ושימוש שגוי בהן עלול לפגוע בביצועים. כדי לקבל את התוצאות הטובות ביותר, מומלץ לבצע טעינת נתונים מראש או אחסון מראש באופן סלקטיבי בלבד.
לסיכום:
- כדאי להשתמש בטעינה מראש למשאבים שזוהו מאוחר אבל הם חיוניים לדף הנוכחי.
- משתמשים באחזור מראש למשאבים שנדרשים למסלול ניווט עתידי או לפעולה של משתמש.
בשלב הזה, לא כל הדפדפנים תומכים גם בטעינה מראש וגם בטעינה מראש מבוססת-בקשה. כלומר, יכול להיות שלא כל המשתמשים באפליקציה יבחינו בשיפורים בביצועים.
במאמרים הבאים תוכלו לקרוא מידע נוסף על היבטים ספציפיים של ההשפעה של טעינה מראש ושליפה מראש (prefetch) על דף האינטרנט: