כדי לשפר את מהירות הטעינה, יש לטעון מראש נכסים קריטיים

בפתיחת דף אינטרנט, הדפדפן מבקש את מסמך ה-HTML משרת, מנתח את התוכן שלו ושולח בקשות נפרדות לכל משאב שיש אליו הפניה. כמפתח, אתה כבר יודע על כל המשאבים הנדרשים לדף שלך ואילו מהם החשובים ביותר. אפשר להשתמש בידע הזה כדי לבקש את המשאבים הקריטיים מראש ולזרז את תהליך הטעינה. בפוסט הזה מוסבר איך לעשות את זה באמצעות <link rel="preload">.

איך פועלת הטעינה מראש

הטעינה מראש מתאימה במיוחד למשאבים בדרך כלל בדפדפן מתגלה מאוחר.

צילום מסך של החלונית Chrome DevTools Network.
בדוגמה הזו, הגופן Pacifico מוגדר בגיליון הסגנונות באמצעות כלל @font-face. הדפדפן טוען את קובץ הגופן רק לאחר שההורדה והניתוח של גיליון הסגנונות מסתיים.

על ידי טעינה מראש של משאב מסוים, אתם אומרים לדפדפן שאתם רוצים לאחזר אותו מוקדם יותר מכפי שהדפדפן יגלה אותו, מפני שאתם בטוחים שמשאב זה חשוב לדף הנוכחי.

צילום מסך של החלונית &#39;רשת הכלים למפתחים ב-Chrome&#39; אחרי החלת הטעינה מראש.
בדוגמה הזו, הגופן Pacifico נטען מראש, כך שההורדה מתבצעת במקביל לגיליון הסגנונות.

שרשרת הבקשות הקריטית מייצגת את סדר המשאבים שמקבלים עדיפות ומאחזרים על ידי הדפדפן. Lighthouse מזהה נכסים ברמה השלישית של השרשרת הזו כנכסים שהתגלו מאוחר יותר. אפשר להשתמש בביקורת של בקשות מפתח לטעינה מראש כדי לזהות אילו משאבים לטעון מראש.

בדיקה של בקשות מפתחות לטעינה מראש של Lighthouse.

כדי לטעון מראש משאבים, צריך להוסיף את התג <link> עם התג rel="preload" לראש המסמך ב-HTML:

<link rel="preload" as="script" href="critical.js">

הדפדפן שומר במטמון משאבים שנטענו מראש, כדי שהם יהיו זמינים באופן מיידי במקרה הצורך. (הוא לא מפעיל את הסקריפטים או מחיל את גיליונות הסגנונות).

טיפים למשאבים, כמו preconnect ו-prefetch, מופעלים לפי הצורך של הדפדפן. לעומת זאת, preload הוא שדה חובה של הדפדפן. דפדפנים מודרניים כבר די טובים במתן עדיפות למשאבים, לכן חשוב להשתמש ב-preload בכמות מצומצמת ולטעון מראש רק את המשאבים הקריטיים ביותר.

טעינות מראש שלא נעשה בהן שימוש גורמות להצגת אזהרה של Console ב-Chrome, כ-3 שניות לאחר האירוע load.

אזהרה במסוף כלי הפיתוח של Chrome לגבי משאבים שנטענים מראש שלא נמצאים בשימוש.

תרחישים לדוגמה

טעינה מראש של משאבים שהוגדרו ב-CSS

גופנים שמוגדרים עם כללי @font-face או תמונות רקע שמוגדרים בקובצי CSS לא מאותרים עד שהדפדפן מוריד ומנתח את קובצי ה-CSS האלה. טעינה מראש של המשאבים האלה מבטיחה שהם יאוחזרו לפני שקובצי ה-CSS יורדו.

טעינה מראש של קובצי CSS

אם משתמשים בגישה של שירותי CSS חיוניים, צריך לפצל את ה-CSS לשני חלקים. ה-CSS הקריטי שנדרש לעיבוד התוכן שבחלק העליון והקבוע מודגש ב-<head> של המסמך, ובדרך כלל מתבצעת טעינה מדורגת של JavaScript ב-CSS שאינו קריטי. המתנה להפעלת JavaScript לפני טעינת CSS שאינו קריטי עלולה לגרום לעיכובים בעיבוד כשמשתמשים גוללים, ולכן כדאי להשתמש ב-<link rel="preload"> כדי להתחיל את ההורדה מוקדם יותר.

טעינה מראש של קובצי JavaScript

מכיוון שדפדפנים לא מפעילים קבצים שנטענו מראש, טעינה מראש היא שימושית כדי להפריד בין האחזור מהביצוע, שיכול לשפר מדדים כמו משך הזמן עד לפעילות מלאה. הטעינה מראש פועלת בצורה הטובה ביותר אם מפצלים את חבילות JavaScript וטוענים מראש רק חלקים קריטיים.

איך מטמיעים את rel=preload

הדרך הפשוטה ביותר להטמיע את preload היא להוסיף את התג <link> ל-<head> של המסמך:

<head>
  <link rel="preload" as="script" href="critical.js">
</head>

הוספת המאפיין as עוזרת לדפדפן להגדיר את העדיפות של המשאב שנשלף מראש לפי הסוג שלו, להגדיר את הכותרות הנכונות ולקבוע אם המשאב כבר קיים במטמון. הערכים הקבילים למאפיין הזה הם: script, style, font, image ומאפיינים אחרים.

סוגים מסוימים של משאבים, כמו גופנים, נטענים במצב אנונימי. לגבי נכסים שבהם צריך להגדיר את המאפיין crossorigin עם preload:

<link rel="preload" href="ComicSans.woff2" as="font" type="font/woff2" crossorigin>

רכיבי <link> מקבלים גם מאפיין type, שמכיל את סוג ה-MIME של המשאב המקושר. הדפדפנים משתמשים בערך של המאפיין type כדי לוודא שהמשאבים נטענים מראש רק אם סוג הקובץ שלהם נתמך. אם דפדפן לא תומך בסוג המשאב שצוין, המערכת תתעלם מה-<link rel="preload">.

ניתן גם לטעון מראש כל סוג של משאב באמצעות כותרת ה-HTTP Link:

Link: </css/style.css>; rel="preload"; as="style"

היתרון של ציון preload בכותרת ה-HTTP הוא שהדפדפן לא צריך לנתח את המסמך כדי לגלות אותו. מצב כזה יכול להציע שיפורים קלים במקרים מסוימים.

טעינה מראש של מודולי JavaScript באמצעות Webpack

אם אתם משתמשים ב-mod Bundler שיוצר קובצי build של האפליקציה, צריך לבדוק אם הוא תומך בהחדרה של תגי טעינה מראש. בחבילת אינטרנט בגרסה 4.6.0 ואילך, טעינה מראש נתמכת על ידי שימוש בהערות קסם בתוך import():

import(_/* webpackPreload: true */_ "CriticalChunk")

אם משתמשים בגרסה ישנה יותר של Webpack, צריך להשתמש בפלאגין של צד שלישי כמו preload-webpack-plugin.

ההשפעות של טעינה מראש על מדדי ליבה לבדיקת חוויית המשתמש באתר

טעינה מראש היא אופטימיזציה מתקדמת של ביצועים שיש לה השפעה על מהירות הטעינה. אופטימיזציות כאלה עשויות להוביל לשינויים במדדי הליבה לבדיקת חוויית המשתמש באתר, וחשוב להיות מודעים להן.

Largest Contentful Paint (LCP)

לטעינה מראש יש השפעה חזקה על המהירות שבה נטען רכיב התוכן הכי גדול (LCP) בכל הנוגע לגופנים ותמונות, כי גם תמונות וגם צמתים של טקסט יכולים להיות מועמדים ל-LCP. רמז לטעינה מראש שמוצג במיקום טוב יכול לשפר את הביצועים של תמונות ראשיות (Hero) ורצפים גדולים של טקסט שמוצגים באמצעות גופני אינטרנט, וצריך להשתמש בהם אם יש הזדמנויות לספק את קטעי התוכן החשובים למשתמש מהר יותר.

עם זאת, מומלץ להפעיל שיקול דעת בכל הנוגע לטעינה מראש ולאופטימיזציות אחרות. באופן ספציפי, כדאי להימנע מטעינה מראש של יותר מדי משאבים. אם מקבלים עדיפות של יותר מדי משאבים, למעשה אף אחד מהם לא מקבל עדיפות. ההשפעות של רמזים לטעינה מראש מופרזת יהיו מזיקים במיוחד ברשתות איטיות יותר, שבהן התחרות על רוחב הפס תהיה ברורה יותר.

במקום זאת, התמקדו במספר משאבים בעלי ערך גבוה שיפיקו תועלת מטעינה מראש שממוקמת בצורה נכונה. בעת טעינה מראש של גופנים, חשוב לוודא שאתם מציגים גופנים בפורמט WOFF 2.0 כדי לקצר ככל האפשר את זמן הטעינה של המשאבים. בגרסה WOFF 2.0 יש תמיכה מצוינת בדפדפן, לכן שימוש בפורמטים ישנים יותר כמו WOFF 1.0 או TrueType (TTF) יעכב את מכשיר ה-LCP אם מועמד ה-LCP הוא צומת של טקסט.

בכל הנוגע ל-LCP ול-JavaScript, מומלץ לוודא שאתם שולחים תגי עיצוב מלאים מהשרת כדי שסורק הטעינה מראש של הדפדפן יפעל כראוי. אם אתם מציגים חוויה שמסתמכת לחלוטין על JavaScript כדי לעבד תגי עיצוב ואין לכם אפשרות לשלוח HTML שעבר עיבוד של השרת, כדאי להוסיף שלב שבו סורק הטעינה מראש של הדפדפן לא יכול לעשות זאת, ולטעון מראש משאבים שהיו גלויים רק לאחר סיום הטעינה והביצוע של ה-JavaScript.

Cumulative Layout Shift (CLS)

Cumulative Layout Shift (CLS) הוא מדד חשוב במיוחד כשמדובר בגופני אינטרנט, ול-CLS יש אינטראקציה משמעותית עם גופני אינטרנט שמשתמשים במאפיין ה-CSS font-display כדי לנהל את אופן הטעינה של הגופנים. כדי לצמצם את שינויי הפריסה שקשורים לגופנים באינטרנט, כדאי להשתמש באסטרטגיות הבאות:

  1. טעינה מראש של גופנים תוך שימוש בערך ברירת המחדל block עבור font-display. זהו איזון עדין. חסימת התצוגה של גופנים ללא חלופה יכולה להיחשב כבעיה בחוויית המשתמש. מצד אחד, טעינת גופנים באמצעות font-display: block; מונעת שינויי פריסה שקשורים לגופנים באינטרנט. מצד שני, עדיין תרצה לטעון את גופני האינטרנט האלה בהקדם האפשרי, אם הם חיוניים לחוויית המשתמש. שילוב של טעינה מראש עם font-display: block; עשוי להיות פשרה סבירה.
  2. טעינה מראש של גופנים תוך שימוש בערך fallback עבור font-display. fallback הוא הסכם בין swap לבין block, כי תקופת החסימה שלו קצרה מאוד.
  3. שימוש בערך optional עבור font-display ללא טעינה מראש. אם גופן אינטרנט אינו חיוני לחוויית המשתמש, אבל הוא עדיין משמש לעיבוד כמות משמעותית של טקסט בדף, כדאי להשתמש בערך optional. בתנאים גרועים, optional יציג טקסט של דף בגופן חלופי בזמן שהוא יטען את הגופן ברקע לצורך הניווט הבא. התוצאה נטו בתנאים האלה היא CLS משופר, מאחר שגופנים של המערכת יוצגו באופן מיידי, בעוד שטעינות דפים נוספות ייטענו את הגופן באופן מיידי ללא שינויים בפריסה.

בכל הנוגע לגופני אינטרנט, המדד CLS הוא מדד שקשה לבצע אופטימיזציה לפיו. כמו תמיד, אתם יכולים לערוך ניסויים בשיעור ה-Lab, אבל כדאי לסמוך על נתוני השטח שלכם ולראות אם האסטרטגיות לטעינת גופנים משפרות את ה-CLS או מחמירים אותו.

מאינטראקציה ועד הצגת התגובה (INP)

Interaction to Next Paint הוא מדד שמודד את רמת הרספונסיביות לקלט של המשתמשים. מאחר שחלקו של האריה באינטראקטיביות באינטרנט מונע על ידי JavaScript, טעינה מראש של JavaScript שמפעילה אינטראקציות חשובות עשויה לעזור להפחית את ה-INP של דף. עם זאת, חשוב לזכור שלטעינה מראש של יותר מדי JavaScript במהלך ההפעלה עלולות להיות השלכות שליליות בלתי רצויות אם יותר מדי משאבים מתמודדים על רוחב הפס.

מומלץ גם להפעיל שיקול דעת לגבי פיצול קוד. פיצול קוד הוא אופטימיזציה מצוינת לצמצום כמות ה-JavaScript שנטען במהלך ההפעלה, אך אינטראקציות עשויות להתעכב אם הן מסתמכות על JavaScript שנטען ישירות בתחילת האינטראקציה. כדי לפצות על כך, צריך לבדוק את כוונת המשתמש ולהזריק טעינה מראש למקטעי ה-JavaScript הנדרשים לפני שהאינטראקציה מתרחשת. דוגמה אחת היא טעינה מראש של JavaScript שנדרש כדי לאמת תוכן של טופס כשמתמקדים באחד מהשדות בטופס.

סיכום

כדי לשפר את מהירות הדף, צריך לטעון מראש משאבים חשובים שהדפדפן מזהה מאוחר יותר. טעינה מראש של כל המידע לא תהיה יעילה, לכן יש להשתמש ב-preload בכמות מצומצמת ולמדוד את ההשפעה בעולם האמיתי.