מדריך מפורט איך לפרק את ה-LCP ולזהות תחומים עיקריים שצריך לשפר.
תאריך פרסום: 30 באפריל 2020
המהירות שבה נטען רכיב התוכן הכי גדול (LCP) הוא אחד משלושת המדדים של מדדי הליבה לבדיקת חוויית המשתמש באתר, והוא מייצג את מהירות הטעינה של התוכן הראשי בדף אינטרנט. באופן ספציפי, המדד LCP מודד את הזמן מהרגע שבו המשתמש מתחיל את הטעינה של הדף ועד שהתמונה או בלוק הטקסט הגדולים ביותר מוצגים באזור התצוגה.
כדי לספק חוויית משתמש טובה, האתרים צריכים לשאוף להגיע ל-LCP של 2.5 שניות או פחות ב-75% לפחות מהביקורים בדפים.
יש כמה גורמים שיכולים להשפיע על המהירות שבה הדפדפן יכול לטעון ולעבד דף אינטרנט, ולעיכובים בכל אחד מהם יכולה להיות השפעה משמעותית על LCP.
לרוב, תיקון מהיר של חלק אחד בדף לא יביא לשיפור משמעותי ב-LCP. כדי לשפר את LCP, צריך לבחון את כל תהליך הטעינה ולוודא שכל שלב בדרך עבר אופטימיזציה.
הסבר על המדד LCP
לפני שמבצעים אופטימיזציה של LCP, המפתחים צריכים לבדוק אם יש להם בעיה ב-LCP ואת מידת החומרה שלה.
אפשר למדוד את LCP במספר כלים, ולא כל הכלים האלה מודדים את LCP באותו אופן. כדי להבין את זמן הטעינה של התוכן הוויזואלי (LCP) של משתמשים אמיתיים, צריך לבדוק את החוויה של המשתמשים בפועל, ולא את מה שמופיע בכלי מבוסס-מעבדה כמו Lighthouse או בבדיקות מקומיות. כלים אלה, המבוססים על מעבדה, יכולים לספק שפע של מידע שיעזור לכם לשפר את מדד ה-LCP, אבל חשוב לזכור שבדיקות מעבדה בלבד לא בהכרח מייצגות את החוויה של המשתמשים בפועל.
אפשר להציג נתוני LCP שמבוססים על משתמשים אמיתיים באמצעות כלים למעקב אחר משתמשים אמיתיים (RUM) שמותקנים באתר, או באמצעות הדוח על חוויית המשתמש ב-Chrome (CrUX), שבו נאספים נתונים אנונימיים ממשתמשי Chrome אמיתיים עבור מיליוני אתרים.
שימוש בנתוני LCP של CrUX בכלי הפיתוח ל-Chrome
בחלונית 'ביצועים' בכלי הפיתוח ל-Chrome מוצגת חוויית ה-LCP המקומית לצד מדד ה-LCP של הדף או המקור ב-CrUX, בתצוגת המדדים החיים.
כשמשתמשים בשכבות של נתוני שדה בחלונית 'ביצועים', אפשר להעריך אם יש בדף בעיות LCP של משתמשים אמיתיים ולהתאים את ההגדרות של הסביבה המקומית כדי לשחזר את הבעיות האלה ולפתור אותן בצורה טובה יותר.
שימוש בנתוני LCP של CrUX ב-PageSpeed Insights
PageSpeed Insights מספק גישה לנתוני CrUX בקטע העליון שכותרתו רוצה נתונים על החוויה של המשתמשים באתר בפועל?. נתונים מפורטים יותר מהבדיקה זמינים בקטע התחתון אבחון בעיות בביצועים. אם נתוני CrUX זמינים לאתר שלכם, מומלץ תמיד להתמקד קודם בנתוני המשתמשים האמיתיים.
הכלי PageSpeed Insights מציג עד ארבעה נתוני CrUX שונים:
- נתוני נייד של כתובת ה-URL הזו
- נתוני מחשב עבור כתובת ה-URL הזו
- נתוני נייד של כל המקור
- נתוני מחשב לגבי כל המקור
אפשר להפעיל או להשבית את האפשרויות האלה באמצעות הלחצנים שבחלק העליון ובפינה השמאלית העליונה של הקטע הזה. אם אין לכתובת URL מספיק נתונים כדי להציג אותה ברמת כתובת ה-URL, אבל יש נתונים לגבי המקור, מערכת PageSpeed Insights תמיד מציגה את נתוני המקור.
זמן הטעינה של רכיב LCP של המקור כולו עשוי להיות שונה מאוד מזמן הטעינה של רכיב LCP בדף ספציפי, בהתאם לאופן שבו רכיב LCP נטען בדף הזה בהשוואה לדפים אחרים במקור הזה. הוא יכול להיות מושפע גם מהאופן שבו המבקרים מנווטים לדפים האלה. משתמשים חדשים נוטים לבקר בדפי הבית, ולכן הם נטענים לעיתים קרובות 'קרים', ללא תוכן שנשמר במטמון, ולכן הם לרוב הדפים האיטיים ביותר באתר.
בדיקת ארבע הקטגוריות השונות של נתוני CrUX יכולה לעזור לכם להבין אם בעיית LCP היא ספציפית לדף הזה או בעיה כללית יותר באתר. באופן דומה, אפשר לראות אילו סוגי מכשירים נתקלים בבעיות LCP.
שימוש במדדים המשניים של CrUX ב-PageSpeed Insights
אם אתם רוצים לבצע אופטימיזציה של LCP, כדאי לכם להשתמש גם בזמנים של הצגת תוכן ראשוני (FCP) ושל זמן לבייט הראשון (TTFB). אלה מדדים טובים לאבחון שיכולים לספק תובנות חשובות לגבי LCP.
TTFB הוא הזמן מרגע שהמבקרים מתחילים לנווט לדף (למשל, לוחצים על קישור) ועד לקבלת הבייטים הראשונים של מסמך ה-HTML. זמן אחזור ראשוני ארוך עלול להקשות על השגת זמן LCP של 2.5 שניות, או אפילו להפוך את השגת הזמן הזה לבלתי אפשרית.
זמן אחזור אתר ארוך יכול לנבוע מכמה הפניות אוטומטיות לשרת, ממבקרים שנמצאים רחוק מהשרת הקרוב ביותר של האתר, ממבקרים שנמצאים בתנאים ירודים של רשת או מחוסר יכולת להשתמש בתוכן ששמור במטמון בגלל פרמטרים של שאילתות.
לאחר עיבוד דף, עשוי להופיע צבע ראשוני (לדוגמה, צבע הרקע), ואחריו תוכן מסוים (לדוגמה, כותרת האתר). המדד 'הצגת תוכן ראשוני (FCP)' מודד את ההופעה של התוכן הראשוני. ההפרש בין מדד FCP לבין מדדים אחרים יכול להיות משמעותי מאוד.
אם יש דלתא גדולה בין השדה TicketFB ל-FCP, יכול להיות שהדפדפן צריך להוריד הרבה נכסים שחוסמים רינדור. יכול להיות גם שמדובר בסימן לכך שהאתר צריך לבצע הרבה עבודה כדי להציג תוכן בעל משמעות – סימן קלאסי לאתר שמסתמך במידה רבה על עיבוד בצד הלקוח.
אם יש פער גדול בין FCP ל-LCP, סימן שמשאבי ה-LCP לא זמינים באופן מיידי לדפדפן כדי לתת להם עדיפות (לדוגמה, טקסט או תמונות שמנוהלים על ידי JavaScript ולא זמינים ב-HTML הראשוני), או שהדפדפן משלים משימות אחרות לפני שהוא יכול להציג את תוכן ה-LCP.
שימוש בנתוני Lighthouse של PageSpeed Insights
בקטע Lighthouse בכלי PageSpeed Insights מפורטות כמה הנחיות לשיפור ה-LCP, אבל קודם כדאי לבדוק אם ה-LCP שצוין תואם באופן כללי לנתוני משתמשים אמיתיים שסופקו על ידי CrUX. אם אין הסכמה בין Lighthouse ומ-CrUX, סביר להניח ש-CrUX מספק תמונה מדויקת יותר של חוויית המשתמש שלכם. לפני שמבצעים פעולה בנתונים, חשוב לוודא שנתוני CrUX שייכים לדף שלכם, ולא למקור המלא.
אם גם ב-Lighthouse וגם ב-CrUX מוצגים ערכים של LCP שדורשים שיפור, בקטע Lighthouse תוכלו למצוא הנחיות חשובות לגבי דרכים לשיפור LCP. אפשר להשתמש במסנן LCP כדי להציג רק ביקורות שרלוונטיות ל-LCP באופן הבא:
בנוסף להזדמנויות לשיפור, יש מידע אבחוני שעשוי לספק מידע נוסף שיעזור לאבחן את הבעיה. האבחון רכיב ה-LCP מציג פירוט שימושי של הזמנים השונים שמרכיבים את ה-LCP:
בהמשך נתעמק בחלקים המשניים האלה.
פירוט של LCP
אופטימיזציה של LCP יכולה להיות משימה מורכבת יותר אם כלי PageSpeed Insights לא מספק לכם תשובה לשאלה איך לשפר את המדד הזה. כשמדובר במשימות מורכבות, בדרך כלל עדיף לפצל אותן למשימות קטנות יותר שניתן לנהל בקלות, ולטפל בכל אחת מהן בנפרד.
בקטע הזה נסביר איך לפרק את LCP לחלקי המשנה הקריטיים ביותר שלו, ולאחר מכן נציג המלצות ספציפיות ושיטות מומלצות לביצוע אופטימיזציה של כל חלק.
רוב הטעינות של דפים כוללות בדרך כלל מספר בקשות לרשת, אבל כדי לזהות הזדמנויות לשיפור ה-LCP, כדאי להתחיל ולבחון רק שתי בקשות:
- מסמך ה-HTML הראשוני
- משאב ה-LCP (אם רלוונטי)
בקשות אחרות בדף יכולות להשפיע על נתוני LCP, אבל שתי הבקשות האלה – בייחוד השעות שבהן משאב ה-LCP מתחיל ומסתיים – קובעות אם הדף עבר אופטימיזציה ל-LCP.
כדי לזהות את המשאב של LCP, אפשר להשתמש בכלים למפתחים (כמו PageSpeed Insights שצוין קודם, כלי הפיתוח ל-Chrome או WebPageTest) כדי לקבוע את רכיב ה-LCP. משם תוכלו להתאים את כתובת ה-URL (שוב, אם רלוונטי) שנטענה על ידי הרכיב בWaterfall של רשת, בכל המשאבים שנטענו על ידי הדף.
לדוגמה, בתצוגה החזותית הבאה המשאבים האלה מודגשים בתרשים רשימת משימות של רשת לטעינת דף אופיינית, שבו רכיב ה-LCP דורש בקשה להצגת תמונה.
כדי שהדף יהיה מותאם בצורה טובה, כדאי שהבקשה למשאב ה-LCP תתחיל להיטען בהקדם האפשרי, ושהרכיב ה-LCP יעבד בהקדם האפשרי אחרי שסיום טעינת משאב ה-LCP. כדי להמחיש אם דף מסוים עומד בעיקרון הזה או לא, אפשר לפלח את זמן ה-LCP הכולל לחלקים המשנה הבאים:
- זמן לקבלת בייט התגובה הראשון (TTFB)
- הזמן מהרגע שבו המשתמש מתחיל את הטעינה של הדף ועד שהדפדפן מקבל את הבייט הראשון בתגובה של מסמך ה-HTML.
- עיכוב בטעינת המשאבים
- הזמן שחלף מ-TTFB ועד שהדפדפן התחיל לטעון את משאב ה-LCP. אם אלמנט ה-LCP לא דורש טעינת משאבים לצורך רינדור (לדוגמה, אם האלמנט הוא צומת טקסט שעבר רינדור בגופן מערכת), הזמן הזה הוא 0.
- משך הזמן של טעינת משאבים
- משך הזמן שנדרש כדי לטעון את משאב ה-LCP עצמו. אם רכיב ה-LCP לא דורש טעינת משאבים כדי להציג, הזמן הזה הוא 0.
- עיכוב בעיבוד הרכיב
- הזמן שחלף בין סיום טעינת המשאב של LCP לבין הזמן שבו רכיב LCP עבר רינדור מלא.
מדד ה-LCP של כל דף מורכב מארבע קטגוריות המשנה האלה. אין פער או חפיפה ביניהם, והם מצטברים לזמן LCP המלא.
הערך של LCP בכל דף יכול להתפרק לארבעת החלקים המשניים האלה. אין חפיפה או פער ביניהם. בסך הכול, הם מרכיבים את משך ה-LCP המלא.
כשמבצעים אופטימיזציה של LCP, מומלץ לנסות לבצע אופטימיזציה של החלקים המשניים האלה בנפרד. אבל חשוב גם לזכור שצריך לבצע אופטימיזציה של כולם. במקרים מסוימים, אופטימיזציה שחלה על חלק אחד לא תשפר את LCP, אלא רק תעביר את הזמן שנחסך לחלק אחר.
לדוגמה, בתרשים רשימת הרשתות הקודם, אם תקטינו את גודל הקובץ של התמונה על ידי דחיסתה יותר או מעבר לפורמט אופטימלי יותר (כמו AVIF או WebP), משך טעינת המשאב יהיה קצר יותר, אבל זמן ה-LCP לא ישתפר כי הזמן פשוט יועבר לחלק המשני עיכוב עיבוד הרכיב:
הסיבה לכך היא שבדף הזה, רכיב ה-LCP מוסתר עד שהטעינה של קוד ה-JavaScript מסתיימת, ואז הכל נחשף בבת אחת.
הדוגמה הזו ממחישה את הנקודה שצריך לבצע אופטימיזציה של כל חלקי המשנה האלה כדי להשיג את תוצאות ה-LCP הטובות ביותר.
זמני חלקים משניים אופטימליים
כדי לבצע אופטימיזציה של כל חלק משנה של LCP, חשוב להבין מהו הפירוט האידיאלי של החלקים האלה בדף שעברו אופטימיזציה טובה.
מתוך ארבעת החלקים המשניים, בשני השמות מופיעה המילה 'delay' (עיכוב). זהו רמז לכך שכדאי שהזמנים האלה יהיו קרובים לאפס ככל האפשר. שני החלקים האחרים כוללים בקשות לרשת, שתהליך הטיפול בהן אורך זמן.
חשוב לזכור שהחלוקות האלה לזמנים הן הנחיות, ולא כללים קפדניים. אם זמני ה-LCP בדפים שלכם נעים בטווח של 2.5 שניות באופן עקבי, לא משנה באמת מהם היחסים היחסיים. עם זאת, אם אתם מבזבזים הרבה זמן מיותר באחד מהחלקים של 'השהיה', יהיה מאוד קשה להגיע ליעדים של 2.5 שניות באופן קבוע.
דרך טובה לחשוב על פירוט זמן ה-LCP היא:
- רוב זמן ה-LCP צריך להיות מוקדש לטעינה של מסמך ה-HTML ומקור ה-LCP.
- כל שלב לפני ה-LCP שבו אחד משני המשאבים האלה לא נטען הוא הזדמנות לשיפור.
איך מבצעים אופטימיזציה של כל חלק
עכשיו, אחרי שהבנתם איך צריכים להתפרסם זמני החלק המשני של LCP בדף שעברו אופטימיזציה, אתם יכולים להתחיל לבצע אופטימיזציה של הדפים שלכם.
בארבעת הקטעים הבאים נספק המלצות ושיטות מומלצות לביצוע אופטימיזציה של כל חלק. הן מוצגות לפי הסדר, החל באופטימיזציות שצפויות להניב את ההשפעה הגדולה ביותר.
1. ביטול העיכוב בטעינת המשאבים
המטרה בשלב הזה היא להבטיח שמשאב ה-LCP יתחיל להיטען בהקדם האפשרי. באופן תיאורטי, המועד המוקדם ביותר שבו משאב יכול להתחיל לטעון הוא מיד אחרי זמן אחזור ה-TTFB, אבל בפועל תמיד יש עיכוב מסוים לפני שהדפדפנים מתחילים לטעון משאבים בפועל.
כלל טוב הוא שמשאב ה-LCP צריך להתחיל לטעון באותו זמן שבו נטען המשאב הראשון על ידי הדף הזה. במילים אחרות, אם משאב ה-LCP מתחיל להיטען מאוחר יותר מהמשאב הראשון, יש מקום לשיפור.
באופן כללי, יש שני גורמים שמשפיעים על המהירות שבה משאב LCP יכול להיטען:
- כשהמשאב מתגלה.
- העדיפות של המשאב.
ביצוע אופטימיזציה כשהמשאב מתגלה
כדי לוודא שמשאבי ה-LCP יתחילו לטעון מוקדם ככל האפשר, חשוב מאוד שסורק הטעינה מראש של הדפדפן יוכל לזהות את המשאב בתגובה הראשונית של מסמך ה-HTML. לדוגמה, במקרים הבאים הדפדפן יכול לגלות את משאב ה-LCP על ידי סריקת התגובה של מסמך ה-HTML:
- אלמנט ה-LCP הוא אלמנט
<img>
, והמאפייניםsrc
אוsrcset
שלו נמצאים בסימון ה-HTML הראשוני. - רכיב ה-LCP מחייב תמונת רקע ב-CSS, אבל התמונה הזו נטענת מראש באמצעות
<link rel="preload">
בתגי העיצוב של ה-HTML (או באמצעות כותרתLink
). - רכיב ה-LCP הוא צומת טקסט שדורש גופן אינטרנט לעיבוד (רנדור), והגופן נטען באמצעות
<link rel="preload">
בסימון ה-HTML (או באמצעות כותרתLink
).
הנה כמה דוגמאות שבהן לא ניתן למצוא את משאב ה-LCP מסריקת התגובה של מסמך ה-HTML:
- רכיב ה-LCP הוא רכיב
<img>
שמתווסף באופן דינמי לדף באמצעות JavaScript. - אלמנט ה-LCP נטען באיטרציה באמצעות ספריית JavaScript שמסתירה את המאפיינים
src
אוsrcset
שלו (לרוב כ-data-src
אוdata-srcset
). - רכיב ה-LCP מחייב תמונת רקע ב-CSS.
בכל אחד מהמקרים האלה, הדפדפן צריך להריץ את הסקריפט או להחיל את גיליון הסגנונות – שבדרך כלל כרוך בהמתנה לסיום של בקשות הרשת – לפני שהוא יכול לגלות את המשאב של LCP ולהתחיל לטעון אותו. המצב הזה אף פעם לא אופטימלי.
כדי למנוע עיכוב מיותר בטעינת משאבים, משאב ה-LCP צריך להיות גלוי ממקור ה-HTML. במקרים שבהם יש הפניה למשאב רק מקובץ CSS או JavaScript חיצוני, צריך לטעון מראש את משאב ה-LCP עם עדיפות שליפה גבוהה. לדוגמה:
<!-- Load the stylesheet that will reference the LCP image. -->
<link rel="stylesheet" href="/path/to/styles.css">
<!-- Preload the LCP image with a high fetchpriority so it starts loading with the stylesheet. -->
<link rel="preload" fetchpriority="high" as="image" href="/path/to/hero-image.webp" type="image/webp">
אופטימיזציה של העדיפות של המשאב
גם אם משאב ה-LCP גלוי בתווית ה-HTML, עדיין יכול להיות שהוא לא יתחיל להיטען מוקדם כמו המשאב הראשון. מצב כזה יכול לקרות אם שיטות הניתוח של העדיפות של סורק ההטענה המקדימה בדפדפן לא מזהות שהמשאב חשוב, או אם הוא קובע שמשאבים אחרים חשובים יותר.
לדוגמה, אפשר לעכב את תמונת ה-LCP באמצעות HTML אם מגדירים את הערך loading="lazy"
ברכיב <img>
. כשמשתמשים בטעינה איטית, המשאב לא נטען עד שהפריסה מאשרת שהתמונה נמצאת בחלון התצוגה, ולכן הטעינה עשויה להתחיל מאוחר יותר מאשר במקרה אחר.
גם בלי טעינת פריטים בזמן אמת, הדפדפנים לא טוענים תמונות בעדיפות הגבוהה ביותר בשלב הראשון, כי הן לא משאבים שחוסמים את העיבוד. אפשר לרמוז לדפדפן אילו משאבים הם החשובים ביותר באמצעות המאפיין fetchpriority
למשאבים שעדיפות גבוהה יותר יכולה לשפר את הביצועים שלהם:
<img fetchpriority="high" src="/path/to/hero-image.webp">
מומלץ להגדיר את fetchpriority="high"
ברכיב <img>
אם לדעתכם סביר שהוא רכיב ה-LCP של הדף. עם זאת, הגדרת עדיפות גבוהה ליותר מתמונה אחת או שתיים, הופכת את הגדרת העדיפות לא מועילה להפחתת LCP.
אפשר גם להוריד את רמת העדיפות של תמונות שעשויות להופיע מוקדם בתגובה של המסמך אבל לא גלויות בגלל סגנון, כמו תמונות שקובצות בקרוסלה ולא גלויות בזמן ההפעלה:
<img fetchpriority="low" src="/path/to/carousel-slide-3.webp">
אם תבטלו את העדיפות של משאבים מסוימים, תוכלו להקצות יותר רוחב פס למשאבים שזקוקים לו יותר – אבל חשוב להיזהר. תמיד צריך לבדוק את העדיפות של המשאבים בכלי הפיתוח ולבדוק שינויים באמצעות כלים לשיעור Lab ולשימוש בשטח.
אחרי שתבצעו אופטימיזציה של תזמון הגילוי והעדיפות של משאב ה-LCP, רשימת הרשתות בתצוגת המפל אמורה להיראות כך (משאב ה-LCP מתחיל באותו זמן כמו המשאב הראשון):
2. ביטול העיכוב בעיבוד הרכיב
המטרה של השלב הזה היא לוודא שרכיב ה-LCP יוכל להירטן מיד אחרי שהמשאב שלו יסיים לטעון, לא משנה מתי זה יקרה.
הסיבה העיקרית שלא ניתן יהיה לעבד את רכיב ה-LCP מיד לאחר סיום הטעינה של המשאב היא אם הרינדור נחסם מסיבה אחרת:
- הטעינה של כל הדף נחסמת בגלל גיליונות סגנונות או סקריפטים סינכרוניים ב-
<head>
שעדיין נטענים. - משאב ה-LCP הסתיים, אבל רכיב ה-LCP עדיין לא נוסף ל-DOM (הוא ממתין לטעינה של קוד JavaScript מסוים).
- הרכיב מוסתר על ידי קוד אחר, כמו ספריית בדיקות A/B שעדיין קובעת באיזה ניסוי המשתמש צריך להשתתף.
- ה-thread הראשי חסום בגלל משימות ארוכות, ועבודות העיבוד צריכות להמתין עד שהמשימות הארוכות האלה יסתיימו.
בקטעים הבאים מוסבר איך לטפל בסיבות הנפוצות ביותר לעיכוב מיותר בעיבוד הרכיב.
צמצום או הטמעה בקוד של גיליונות סגנונות שחוסמים את העיבוד
גיליונות סגנונות שנטענים מתיוג ה-HTML ימנעו את העיבוד של כל התוכן שמופיע אחריהם. זה טוב, כי בדרך כלל לא רוצים לעבד HTML ללא סגנון. עם זאת, אם גיליון הסגנונות גדול כל כך שמשך הטעינה שלו ארוך בהרבה מזה של משאב ה-LCP, הוא ימנע את העיבוד של אלמנט ה-LCP – גם אחרי שהמשאב שלו יסיים להיטען, כפי שמוצג בדוגמה הבאה:
כדי לפתור את הבעיה, עומדות לרשותכם האפשרויות הבאות:
- להוסיף את גיליון הסגנונות לקוד ה-HTML כדי למנוע את הבקשה הנוספת לרשת. לחלופין,
- להקטין את הגודל של גיליון הסגנונות.
באופן כללי, מומלץ להטמיע את גיליון הסגנונות רק אם הוא קטן, כי תוכן שמוטמע ב-HTML לא יכול ליהנות מהאחסון במטמון בטעינות של דפים הבאות. אם גיליון סגנונות כל כך גדול עד שהטעינה שלו נמשכת זמן רב יותר ממשאב ה-LCP, סביר להניח שהוא לא יכול להיות מתאים להוספה אוטומטית.
ברוב המקרים, הדרך הטובה ביותר לוודא שגיליון הסגנונות לא חוסם את העיבוד של אלמנט ה-LCP היא לצמצם את הגודל שלו כך שיהיה קטן יותר ממשאב ה-LCP. כך תוכלו לוודא שהיא לא צוואת בקבוק ברוב הביקורים.
הנה כמה המלצות להקטנת הגודל של גיליון הסגנונות:
- הסרת CSS שלא בשימוש: משתמשים בכלים למפתחים של Chrome כדי למצוא כללי CSS שלא בשימוש ואפשר להסיר אותם (או לדחות אותם).
- דחייה של CSS שאינו קריטי: פיצול גיליון הסגנונות לסגנונות הנדרשים לטעינת דף ראשונית, ולאחר מכן לסגנונות שניתן לטעון באופן מדורג.
- צמצום וקידוד של CSS: לגבי סגנונות חיוניים, חשוב להפחית את גודל ההעברה שלהם ככל האפשר.
דחייה או הטמעה בקוד של JavaScript שחוסם את העיבוד
כמעט אף פעם אין צורך להוסיף סקריפטים סינכרוניים (סקריפטים ללא המאפיינים async
או defer
) ל-<head>
של הדפים, וכמעט תמיד הפעולה הזו תשפיע לרעה על הביצועים.
במקרים שבהם קוד JavaScript צריך לפעול מוקדם ככל האפשר בטעינת הדף, מומלץ להטמיע אותו כדי שהעיבוד לא יתעכב בהמתנה לבקשת רשת אחרת. עם זאת, כמו לגבי גיליונות סגנונות, כדאי להוסיף סקריפטים בקוד רק אם הם קטנים מאוד.
<head> <script src="/path/to/main.js"></script> </head>
<head> <script> // Inline script contents directly in the HTML. // IMPORTANT: only do this for very small scripts. </script> </head>
שימוש ברינדור בצד השרת
רינדור בצד השרת (SSR) הוא התהליך של הרצת לוגיקת האפליקציה בצד הלקוח בשרת ותגובה לבקשות של מסמכי HTML עם תגי העיצוב המלאים של ה-HTML.
מבחינת אופטימיזציה של LCP, יש לשרת הצד הסטטי שני יתרונות עיקריים:
- משאבי התמונות יהיו גלויים ממקור ה-HTML (כפי שמתואר בשלב 1 קודם).
- תוכן הדף לא ידרוש בקשות JavaScript נוספות כדי להסתיים לפני שהוא יוכל להירטן.
החיסרון העיקרי של SSR הוא שהוא דורש זמן עיבוד נוסף בשרת, שעלול להאט את זמן אחזור הבקשה (TTFB). עם זאת, בדרך כלל כדאי להשתמש באפשרות הזו כי זמני העיבוד בשרתים נמצאים בשליטתכם, אבל יכולות הרשת והמכשיר של המשתמשים לא.
אפשרות דומה ל-SSR נקראת יצירת אתר סטטי (SSG) או עיבוד מראש. זהו התהליך של יצירת דפי ה-HTML בשלב build במקום לפי דרישה. אם אפשר לבצע עיבוד מראש בארכיטקטורה שלכם, בדרך כלל זו הבחירה הטובה ביותר מבחינת הביצועים.
פיצול משימות ארוכות
גם אם פעלת לפי העצה הקודמת, וקוד ה-JavaScript לא חוסם רינדור וגם לא אחראי לעיבוד הרכיבים, הוא עדיין עלול לעכב את LCP.
הסיבה הנפוצה ביותר לכך היא כשדפים טוענים קבצי JavaScript גדולים, שצריך לנתח ולהריץ בשרשור הראשי של הדפדפן. כלומר, גם אם משאב התמונה יוריד במלואו, יכול להיות שהוא עדיין יצטרך להמתין עד שסקריפט לא קשור יסיים את הביצוע שלו כדי שיוכל להריץ רינדור.
כל הדפדפנים כיום מבצעים עיבוד תמונות בשרשור הראשי, כלומר כל דבר שחוסם את השרשור הראשי עלול גם להוביל לעיכוב מיותר בעיבוד הרכיבים.
3. קיצור משך הזמן של טעינת המשאבים
מטרת השלב הזה היא לקצר את הזמן להעברת הבייטים של המשאב ברשת למכשיר של המשתמש. באופן כללי, יש ארבע דרכים לעשות זאת:
- להקטין את הגודל של המשאב.
- צמצום המרחק שהמשאב צריך לעבור.
- הפחתת התחרות על רוחב הפס ברשת.
- להסיר לחלוטין את זמן הרשת.
הקטנת המשאב
משאב ה-LCP של דף (אם יש לו כזה) יהיה תמונה או גופן אינטרנט. המדריכים הבאים מפרטים בצורה מפורטת איך לצמצם את הגודל של שניהם:
הקטנת המרחק שהמשאב צריך לעבור
בנוסף לצמצום גודל המשאב, תוכלו גם לקצר את זמני הטעינה על ידי מיקום השרתים שלכם קרוב ככל האפשר למיקום הגיאוגרפי של המשתמשים. הדרך הטובה ביותר לעשות זאת היא להשתמש ברשת להעברת תוכן (CDN).
רשתות CDN של תמונות מועילות במיוחד, כי הן לא רק מצמצמות את המרחק שהמשאב צריך לעבור, אלא גם מצמצמות את גודל המשאב.
צמצום התחרות על רוחב הפס של הרשת
גם אם תקטינו את גודל המשאב ואת המרחק שהוא צריך לעבור, יכול להיות שטעינת משאב תימשך זמן רב אם תטענו משאבים רבים אחרים בו-זמנית. הבעיה הזו נקראת תחרות ברשת.
אם הקצית למשאב ה-LCP fetchpriority
גבוה והתחלת לטעון אותו בהקדם האפשרי, הדפדפן יעשה כמיטב יכולתו כדי למנוע ממשאבים בעדיפות נמוכה יותר להתחרות בו. עם זאת, אם אתם מעמיסים הרבה משאבים עם ערך fetchpriority
גבוה, או אם אתם פשוט מעמיסים הרבה משאבים באופן כללי, הדבר עשוי להשפיע על מהירות הטעינה של משאב ה-LCP.
ביטול זמן הרשת לחלוטין
הדרך הטובה ביותר לקצר את משך הזמן לטעינת המשאבים היא להוציא את הרשת מהתהליך לגמרי. אם אתם מציגים את המשאבים שלכם באמצעות מדיניות יעילה של בקרת מטמון, אז למבקרים שמבקשים את המשאבים האלה בפעם השנייה הם יוצגו מהמטמון – כך שמשך הטעינה של המשאבים יהיה אפס!
אם משאב ה-LCP הוא גופן אינטרנט, בנוסף להקטנת גודל הגופן באינטרנט, כדאי גם לשקול אם צריך לחסום את העיבוד בטעינת משאב הגופן באינטרנט. אם תגדירו ערך של font-display
שהוא לא auto
או block
, הטקסט תמיד יהיה גלוי במהלך הטעינה, ו-LCP לא ייחסם בבקשה נוספת מהרשת.
לסיום, אם משאב ה-LCP קטן, כדאי להוסיף את המשאבים לקוד ככתובת URL של נתונים. כך תוכלו גם למנוע את הבקשה הנוספת מהרשת. עם זאת, יש כמה דברים שצריך לזכור כשמשתמשים בכתובות URL של נתונים, כי לא ניתן לשמור את המשאבים במטמון, ובמקרים מסוימים הם עלולים לגרום לעיכובים ארוכים יותר ברינדור בגלל עלות הפענוח הנוספת.
4. צמצום הזמן לקבלת בייט התגובה הראשון (TTFB)
המטרה של השלב הזה היא לספק את קוד ה-HTML הראשוני במהירות האפשרית. השלב הזה מופיע אחרון כי לרוב למפתחים יש הכי פחות שליטה עליו. עם זאת, זהו גם אחד מהשלבים החשובים ביותר, כי הוא משפיע ישירות על כל שלב שמגיע אחריו. שום דבר לא יכול לקרות בחזית עד שהקצה העורפי מעביר את הבייט הראשון של התוכן, כך שכל מה שתוכלו לעשות כדי לזרז את זמן אחזור ה-First Byte ישפר גם את כל מדדי הטעינה האחרים.
סיבה נפוצה לזמן אחזור דף ארוך באתר שזריז בדרך כלל היא מבקרים שמגיעים דרך מספר הפניות אוטומטיות, למשל ממודעות או מקישורים מקוצרים. תמיד כדאי לצמצם את מספר ההפניות האוטומטיות שהמבקרים צריכים לחכות אליהן.
סיבה נפוצה נוספת היא מצב שבו אי אפשר להשתמש בתוכן ששמור במטמון משרת קצה של CDN, וכל הבקשות צריכות להיות מופנות חזרה לשרת המקור. מצב כזה יכול לקרות אם המבקרים משתמשים בפרמטרים ייחודיים של כתובות URL לצורכי ניתוח נתונים – גם אם הם לא מובילים לדפים שונים.
הנחיות ספציפיות לאופטימיזציה של זמן אחזור ה-TTFB זמינות במדריך לאופטימיזציה של זמן אחזור ה-TTFB.
מעקב אחרי פירוט של LCP ב-JavaScript
נתוני התזמון של כל החלקים המשניים של LCP שצוינו למעלה זמינים ב-JavaScript באמצעות שילוב של ממשקי ה-API הבאים למדידת ביצועים:
היתרון של חישוב ערכי התזמון האלה ב-JavaScript הוא האפשרות לשלוח אותם לספק ניתוח נתונים או לרשום אותם לכלים למפתחים כדי לעזור בניפוי באגים ובאופטימיזציה.
לדוגמה, בצילום המסך הבא נעשה שימוש בשיטה performance.measure()
מ-User Timing API כדי להוסיף עמודות לטראק Timings בחלונית הביצועים של כלי הפיתוח ל-Chrome.
התצוגות החזותיות בערוץ תזמונים מועילות במיוחד כשבודקים אותן לצד הערוצים רשת ושרשור ראשי, כי כך אפשר לראות במבט מהיר מה עוד קורה בדף במהלך פרקי הזמן האלה.
בנוסף להצגה החזותית של החלקים המשניים של LCP בטראק של זמני הטעינה, אפשר גם להשתמש ב-JavaScript כדי לחשב את האחוז של כל חלק משני מתוך זמן ה-LCP הכולל. בעזרת המידע הזה תוכלו לקבוע אם הדפים שלכם עומדים בפירוט האחוזים המומלץ שמתואר למעלה.
בצילום המסך הזה מוצגת דוגמה לתיעוד ביומן של הזמן הכולל של כל חלק משנה של LCP, וגם האחוז שלו מתוך סך כל הזמן של LCP במסוף.
שתי התצוגות החזותיות האלה נוצרו באמצעות הקוד הבא:
const LCP_SUB_PARTS = [
'Time to first byte',
'Resource load delay',
'Resource load duration',
'Element render delay',
];
new PerformanceObserver((list) => {
const lcpEntry = list.getEntries().at(-1);
const navEntry = performance.getEntriesByType('navigation')[0];
const lcpResEntry = performance
.getEntriesByType('resource')
.filter((e) => e.name === lcpEntry.url)[0];
// Ignore LCP entries that aren't images to reduce DevTools noise.
// Comment this line out if you want to include text entries.
if (!lcpEntry.url) return;
// Compute the start and end times of each LCP sub-part.
// WARNING! If your LCP resource is loaded cross-origin, make sure to add
// the `Timing-Allow-Origin` (TAO) header to get the most accurate results.
const ttfb = navEntry.responseStart;
const lcpRequestStart = Math.max(
ttfb,
// Prefer `requestStart` (if TOA is set), otherwise use `startTime`.
lcpResEntry ? lcpResEntry.requestStart || lcpResEntry.startTime : 0
);
const lcpResponseEnd = Math.max(
lcpRequestStart,
lcpResEntry ? lcpResEntry.responseEnd : 0
);
const lcpRenderTime = Math.max(
lcpResponseEnd,
// Use LCP startTime (the final LCP time) because there are sometimes
// slight differences between loadTime/renderTime and startTime
// due to rounding precision.
lcpEntry ? lcpEntry.startTime : 0
);
// Clear previous measures before making new ones.
// Note: due to a bug, this doesn't work in Chrome DevTools.
LCP_SUB_PARTS.forEach((part) => performance.clearMeasures(part));
// Create measures for each LCP sub-part for easier
// visualization in the Chrome DevTools Performance panel.
const lcpSubPartMeasures = [
performance.measure(LCP_SUB_PARTS[0], {
start: 0,
end: ttfb,
}),
performance.measure(LCP_SUB_PARTS[1], {
start: ttfb,
end: lcpRequestStart,
}),
performance.measure(LCP_SUB_PARTS[2], {
start: lcpRequestStart,
end: lcpResponseEnd,
}),
performance.measure(LCP_SUB_PARTS[3], {
start: lcpResponseEnd,
end: lcpRenderTime,
}),
];
// Log helpful debug information to the console.
console.log('LCP value: ', lcpRenderTime);
console.log('LCP element: ', lcpEntry.element, lcpEntry.url);
console.table(
lcpSubPartMeasures.map((measure) => ({
'LCP sub-part': measure.name,
'Time (ms)': measure.duration,
'% of LCP': `${
Math.round((1000 * measure.duration) / lcpRenderTime) / 10
}%`,
}))
);
}).observe({type: 'largest-contentful-paint', buffered: true});
אפשר להשתמש בקוד הזה כפי שהוא לניפוי באגים מקומי, או לשנות אותו כדי לשלוח את הנתונים האלה לספק ניתוח נתונים, וכך לקבל תמונה ברורה יותר של פירוט ה-LCP בדפים שלכם למשתמשים אמיתיים.
סיכום
מדד LCP הוא מורכב, והתזמון שלו עשוי להיות מושפע ממספר גורמים. עם זאת, אם מביאים בחשבון שהאופטימיזציה של LCP מתמקדת בעיקר באופטימיזציה של העומס על משאב ה-LCP, הדברים יכולים להיות פשוטים יותר.
באופן כללי, אפשר לסכם את האופטימיזציה של LCP בארבעה שלבים:
- מוודאים שמשאבי ה-LCP מתחילים להיטען בהקדם האפשרי.
- מוודאים שרכיב ה-LCP יכול לעבור רינדור ברגע שטעינת המשאב שלו מסתיימת.
- כדאי לצמצם את זמן הטעינה של משאב ה-LCP ככל האפשר, בלי להתפשר על האיכות.
- יש לשלוח את מסמך ה-HTML הראשוני מהר ככל האפשר.
אם אתם מצליחים לפעול לפי השלבים האלה בדפים שלכם, אתם יכולים להיות בטוחים שאתם מספקים למשתמשים חוויית טעינה אופטימלית, והדבר אמור למצוא ביטוי בציוני ה-LCP בפועל.