אופטימיזציה של Largest Contentful Paint (LCP)

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

כדי לספק חוויית משתמש טובה, צריך להפעיל באתרים ערך LCP של 2.5 שניות או פחות ל-75% לפחות מהביקורים בדפים.

ערכי LCP טובים הם 2.5 שניות או פחות, ערכים נמוכים הם גדולים מ-4.0 שניות, וכל דבר שביניהם דורש שיפור
ערך LCP טוב הוא 2.5 שניות או פחות.

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

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

הסבר על מדד LCP

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

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

ניתן להציג נתוני LCP שמבוססים על משתמשים אמיתיים מכלים של Real User Monitoring (RUM) שהותקנו באתר, או מדוח חוויית המשתמש ב-Chrome (CrUX), שאוסף נתונים אנונימיים ממשתמשי Chrome אמיתיים עבור מיליוני אתרים.

שימוש בנתוני CrUX ב-PageSpeed Insights

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

נתוני CrUX שמוצגים ב-PageSpeed Insights
נתוני CrUX שמוצגים ב-PageSpeed Insights.

במקרים שבהם CrUX לא מספק נתונים (לדוגמה, במקרה של דף שאין בו מספיק תנועה כדי לקבל נתונים ברמת הדף), אפשר להשלים את CrUX לנתוני RUM שנאספים באמצעות ממשקי JavaScript API שפועלים בדף. כך ניתן גם לספק הרבה יותר נתונים ממה ש-CrUX יכול לחשוף כמערך נתונים ציבורי. בהמשך המדריך נסביר איך לאסוף את הנתונים האלה באמצעות JavaScript.

נתוני LCP

ב-PageSpeed Insights מוצגים עד ארבע קבוצות נתונים שונות של CrUX:

  • נתוני נייד של כתובת ה-URL הזו
  • נתונים במחשב של כתובת ה-URL הזו
  • נתוני נייד לכל המקור
  • נתונים ממחשבים לגבי כל המקור

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

בחזרה ל-PageSpeed Insight לנתונים ברמת המקור כאשר אין נתונים ברמת כתובת ה-URL
כשאין ב-PageSpeed Insights נתונים ברמת כתובת ה-URL, מוצגים נתונים ברמת המקור.

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

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

מדדים משלימים

מפתחים שעובדים על אופטימיזציה של LCP יכולים גם להשתמש בתזמונים של הצגת תוכן ראשוני (FCP) ו-Time to First Byte (TTFB), שהם מדדי אבחון טובים שיכולים לספק תובנות חשובות לגבי LCP.

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

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

אחרי שמתחילים לעבד את התוכן בדף, יכול להיות שיופיע צבע ראשוני (למשל, צבע הרקע) ולאחר מכן יופיע תוכן כלשהו (למשל, כותרת האתר). המראה של התוכן הראשוני נמדד על ידי FCP, וההבדל בין FCP למדדים אחרים יכול להיות משמעותי מאוד.

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

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

שימוש בנתוני PageSpeed Insights Lighthouse

בקטע Lighthouse ב-PageSpeed Insights יש הנחיות לשיפור ה-LCP, אבל קודם כדאי לבדוק אם ה-LCP הנתון תואם באופן כללי לנתוני המשתמשים האמיתיים שסופקו על ידי CrUX. אם יש סתירה בין Lighthouse לבין CrUX, סביר להניח ש-CrUX מספק תמונה מדויקת יותר של חוויית המשתמש. לפני שמבצעים פעולה כלשהי, חשוב לוודא שנתוני ה-CrUX מיועדים לדף ולא למקור המלא.

אם גם ב-Lighthouse וגם ב-CrUX מוצגים ערכי LCP שצריך לשפר, בקטע Lighthouse אפשר למצוא הנחיות חשובות לשיפור ה-LCP. המסנן LCP מאפשר להציג רק ביקורות שרלוונטיות ל-LCP באופן הבא:

הזדמנויות ואבחון LCP של Lighthouse
נתוני אבחון והצעות לשיפור של מדד ה-LCP

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

שלבי LCP ב-Lighthouse
פירוט של רכיבי LCP ב-Lighthouse.

בקטע הבא מתוארות קטגוריות משנה של LCP בפירוט רב יותר.

פירוט LCP

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

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

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

אפשר להשתמש בכלים למפתחים כמו PageSpeed Insights , Chrome DevTools או WebPageTest כדי לזהות את רכיב ה-LCP. משם תוכלו להתאים את כתובת ה-URL (אם רלוונטי) שנטענה על ידי הרכיב ב-Waterfall של הרשת של כל המשאבים שהדף נטען.

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

מפל רשת עם הדגשה של משאבי ה-HTML וה-LCP
תרשים מפל מים שמציג את זמני הטעינה של ה-HTML של דף אינטרנט ואת המשאבים שנדרשים ל-LCP.

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

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

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

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

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

לדוגמה, בדוגמה של ה-Waterfall של הרשת, הקטנת גודל הקובץ של התמונה על ידי דחיסת קובץ גדול יותר או מעבר לפורמט אופטימלי יותר (כמו AVIF או WebP) יפחיתו את זמן הטעינה של המשאב, אבל לא ישפרו את ה-LCP כי הזמן הזה הופך לחלק מעיכוב העיבוד של הרכיב. הסיבה לכך היא שאלמנט ה-LCP מוסתר עד לסיום הטעינה של רכיב ה-JavaScript שמשויך אליו, ולאחר מכן הוא נחשף.

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

זמנים אופטימליים לקטגוריות משנה

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

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

ההתפלגות הבאה היא התפלגות LCP אידיאלית.

חלק משנה LCP אחוז LCP
זמן עד לבייט ראשון (TTFB) ~40%
עיכוב בטעינת משאבים <10%
זמן טעינה של משאב ~40%
עיכוב בעיבוד הרכיבים <10%
TOTAL 100%

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

מומלץ להתייחס לפירוט הזמנים של מדד ה-LCP באופן הבא:

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

איך לבצע אופטימיזציה של כל קטגוריה

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

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

מניעת עיכוב בטעינת משאבים

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

כלל אצבע טוב הוא לוודא שמשאב ה-LCP מתחיל יחד עם המשאב הראשון שהדף נטען.

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

באופן כללי, יש שני גורמים שמשפיעים על מהירות הטעינה של משאב LCP:

  • כשהמשאב מזוהה.
  • איזו עדיפות ניתן למשאב.

ביצוע אופטימיזציה כשהמשאב מתגלה

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

  • רכיב <img> שהמאפיינים src או srcset שלו נמצאים בסימון ה-HTML הראשוני.
  • כל רכיב המחייב תמונת רקע של CSS, כל עוד התמונה נטענת מראש על ידי <link rel="preload"> בתגי העיצוב של HTML (או בכותרת Link).
  • צומת טקסט שמחייב עיבוד של גופן אינטרנט, בתנאי שהגופן נטען מראש על ידי <link rel="preload"> בתגי העיצוב של HTML (או בכותרת Link).

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

  • <img> שנוסף באופן דינמי לדף באמצעות JavaScript.
  • כל רכיב שנטען באופן מדורג באמצעות ספריית JavaScript שמסתירה את מאפייני src או srcset שלו (בדרך כלל data-src או data-srcset).
  • כל רכיב המחייב תמונת רקע של CSS.

כדי למנוע עיכוב מיותר בטעינת המשאבים, צריך שתהיה אפשרות לגלות את משאב ה-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">

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

אחרי האופטימיזציה של העדיפות וזמן הגילוי של משאבי ה-LCP, ה-Waterfall של הרשת אמור להיראות כך, ומשאב ה-LCP יתחיל באותה שעה כמו המשאב הראשון):

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

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

ביטול עיכוב בעיבוד הרכיב

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

הסיבה העיקרית שרכיב ה-LCP לא יוכל להופיע מיד אחרי שטעינת המשאב שלו מסתיימת היא אם הרינדור נחסם מסיבה אחרת:

  • העיבוד של הדף כולו חסום בגלל גיליונות סגנונות או סקריפטים סינכרוניים ב-<head> שעדיין נטענים.
  • הטעינה של משאב ה-LCP הסתיימה, אבל רכיב ה-LCP עדיין לא נוסף ל-DOM כי הוא ממתין לטעינת קוד JavaScript.
  • הרכיב מוסתר על ידי קוד אחר, כמו ספרייה לבדיקות A/B שעדיין לא החליטו לאיזו קבוצה ניסיונית להכניס את המשתמש.
  • ה-thread הראשי חסום בגלל משימות ארוכות, ועבודות העיבוד צריכות להמתין עד שהמשימות הארוכות האלה יושלמו.

בקטעים הבאים מוסבר איך לטפל בסיבות הנפוצות ביותר לעיכוב מיותר של עיבוד רכיבים.

הקטנה או מוטבעת של גיליונות סגנונות לחסימת עיבוד

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

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

כדי לפתור את הבעיה, אפשר:

  • להטביע את גיליון הסגנון בתוך ה-HTML כדי להימנע מבקשת רשת נוספת; או,
  • להקטין את גיליון הסגנונות.

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

דחייה או השהיה של JavaScript החוסם עיבוד מוטבע

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

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

מה מותר לעשות
<head>
  <script>
    // Inline script contents directly in the HTML.
    // IMPORTANT: only do this for very small scripts.
  </script>
</head>
מה אסור לעשות
<head>
  <script src="/path/to/main.js"></script>
</head>

שימוש ברינדור בצד השרת

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

טכנולוגיית SSR עוזרת לבצע אופטימיזציה של LCP בדרכים הבאות:

  • הוא מאפשר לגלות את המשאבים ממקור ה-HTML, כפי שמתואר במאמר ביטול ההשהיה של טעינת משאבים.
  • היא מונעת שהדף שלכם לא יצטרך בקשות נוספות של JavaScript כדי לסיים את העיבוד שלו.

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

כדי לשפר את הביצועים, מומלץ גם ליצור את דפי ה-HTML בשלב build ולא על פי דרישה. השיטה הזו נקראת יצירת אתרים סטטיים (SSG) או עיבוד מראש.

פיצול משימות ארוכות

גם אם פעלתם בהתאם לכל העצות, וקוד ה-JavaScript שלכם לא חוסם את העיבוד או לא אחראי לעיבוד הרכיבים שלכם, הוא עדיין יכול לעכב את ה-LCP.

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

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

קיצור זמן הטעינה של משאבים

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

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

הקטנת גודל המשאב

משאבי LCP הם בדרך כלל תמונות או גופני אינטרנט. במדריכים הבאים מוסבר איך לצמצם את הגדלים של שתי הפלטפורמות:

לצמצם את המרחק של המשאב

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

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

נקודה חשובה: CDNs של תמונות הם דרך נהדרת לקצר את זמני הטעינה של משאבים. עם זאת, שימוש בדומיין של צד שלישי לאירוח התמונות כרוך בתשלום נוסף. חיבור מראש למקור יכול לצמצם חלק מהעלות, אבל האפשרות הטובה ביותר היא להציג תמונות מאותו המקור של מסמך ה-HTML. כדי לאפשר זאת, רשתות CDN רבות מאפשרות להעביר בקשות לשרת proxy מהמקור שלכם.

הפחתת תחרות על רוחב פס של הרשת

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

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

ביטול לחלוטין של זמן הרשת

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

אם משאב ה-LCP הוא גופן אינטרנט, בנוסף להקטנת גודל הגופן באינטרנט, מומלץ לשקול אם צריך לחסום את הרינדור בעת טעינת המשאב של גופן האינטרנט. אם תגדירו ערך font-display של כל דבר מלבד auto או block, הטקסט יופיע תמיד במהלך הטעינה ופונקציית LCP לא תצטרך להמתין לבקשת רשת נוספת.

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

4. הפחתת הזמן לבייט הראשון

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

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

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

לקבלת הנחיות ספציפיות לגבי צמצום TTFB, ראה אופטימיזציה של TTFB.

מעקב אחר פירוט LCP ב-JavaScript

פרטי התזמון של כל קטגוריות המשנה של LCP זמינים ב-JavaScript באמצעות שילוב של ממשקי ה-API הבאים לשיפור הביצועים:

חישוב ערכי התזמון האלה ב-JavaScript מאפשר לשלוח אותם לספק ניתוח נתונים או לרשום אותם לכלים למפתחים כדי לעזור בניפוי באגים ובאופטימיזציה. לדוגמה, בצילום המסך הבא נעשה שימוש בשיטה performance.measure() מה-User Timing API כדי להוסיף עמודות לטראק התזמונים בחלונית הביצועים של כלי הפיתוח ל-Chrome:

מדדי User Timing
  של קטגוריות המשנה LCP שהוצגו באופן חזותי בכלי הפיתוח ל-Chrome
במסלול 'תזמונים' מוצגים לוחות זמנים לקטגוריות המשנה של LCP.

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

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

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

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

שתי התצוגות החזותיות האלה נוצרו באמצעות הקוד הבא:

const LCP_SUB_PARTS = [
  'Time to first byte',
  'Resource load delay',
  'Resource load time',
  '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 באמצעות תוסף Web Vitals

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

צילום מסך של הרישום ביומן במסוף של תוסף Web Vitals, שבו מוצגים התזמונים של חלק המשנה במדד LCP
בחלונית המסוף של התוסף Web Vitals מוצג פירוט של נתוני ה-LCP.