Largest Contentful Paint (LCP)

תמיכה בדפדפנים

  • Chrome: 77.
  • Edge:‏ 79.
  • Firefox: 122.
  • Safari: לא נתמך.

מקור

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

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

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

מה זה LCP?

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

מהו ציון LCP טוב?

כדי לספק חוויית משתמש טובה, צריך לשאוף שהזמן של המדד Largest Contentful Paint יהיה 2.5 שניות או פחות. כדי לוודא שאתם עומדים ביעד הזה עבור רוב המשתמשים, סף טוב למדידה הוא הפרמטר 75th percentile של טעינת הדפים, שמפולח לפי מכשירים ניידים ומחשבים.

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

אילו רכיבים נלקחים בחשבון?

כפי שמצוין כרגע ב-LCP API, סוגי הרכיבים נחשבים ל- Largest Contentful Paint (LCP) הם:

  • רכיבי <img> (זמן ההצגה בפריים הראשון משמש לתוכן מונפש, כמו קובצי GIF או קובצי PNG מונפשים)
  • רכיבי <image> בתוך רכיב <svg>
  • אלמנטים של <video> (הזמן שבו תמונת הפוסטרים נטענת או זמן הצגת הפריים הראשון בסרטונים – המוקדם מביניהם)
  • אלמנט עם תמונת רקע שנטענת באמצעות הפונקציה url() (בניגוד לשיפוע CSS)
  • אלמנטים ברמת הבלוק שמכילים צמתים של טקסט או רכיבי טקסט אחרים ברמת השורה.

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

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

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

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

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

איך נקבע גודל הרכיב?

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

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

ברכיבי טקסט, הפונקציה LCP מתייחסת רק למלבן הקטן ביותר שיכול להכיל את כל צומתי הטקסט.

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

מתי מדווח LCP?

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

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

לדוגמה, בדף עם טקסט ותמונה ראשית, הדפדפן עשוי בהתחלה רק לעבד את הטקסט - לאחר מכן הדפדפן ישלח רשומת largest-contentful-paint שבה המאפיין element יתייחס כנראה ל-<p> או ל-<h1>. מאוחר יותר, ברגע שהטעינה של התמונה הראשית (Hero) תסתיים, תישלח רשומה שנייה של largest-contentful-paint, והמאפיין element שלה יפנה אל <img>.

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

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

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

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

למטרות ניתוח, יש לדווח רק על PerformanceEntry שנשלח לאחרונה לשירות ניתוח הנתונים שלך.

זמן הטעינה לעומת זמן הרינדור

מטעמי אבטחה, חותמת הזמן של עיבוד התמונות לא נחשפת בתמונות ממקורות שונים שחסרה בהן הכותרת Timing-Allow-Origin. במקום זאת, רק זמן הטעינה שלהם נחשף (מכיוון שזמן הטעינה הזה כבר נחשף דרך ממשקי API רבים אחרים לאינטרנט).

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

כשהדבר אפשרי, מומלץ תמיד להגדיר את הכותרת Timing-Allow-Origin כדי שהמדדים יהיו מדויקים יותר.

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

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

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

דוגמאות

הנה כמה דוגמאות למצבים שבהם מוצג ה- Largest Contentful Paint (LCP) בכמה אתרים פופולריים:

ציר הזמן Largest Contentful Paint (LCP) מ-cnn.com
ציר זמן של LCP מ-cnn.com.
ציר הזמן Largest Contentful Paint (LCP) מאתר techcrunch.com
ציר זמן LCP מ-techcrunch.com.

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

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

ציר הזמן Largest Contentful Paint (LCP) מ-instagram.com
ציר זמן LCP מ-instagram.com.
ציר זמן של Largest Contentful Paint מ-google.com
ציר זמן LCP מ-google.com.

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

איך מודדים LCP

אפשר למדוד LCP בשיעור ה-Lab או בשדה, והוא זמין בכלים הבאים:

כלים לשטח

כלים לשיעור Lab

מדידת LCP ב-JavaScript

כדי למדוד את LCP ב-JavaScript, אפשר להשתמש ב-Largest Contentful Paint API. הדוגמה הבאה מראה איך ליצור PerformanceObserver שמקשיב לרשומות של largest-contentful-paint ומרשום אותן במסוף.

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log('LCP candidate:', entry.startTime, entry);
  }
}).observe({type: 'largest-contentful-paint', buffered: true});

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

בקטע הבא מפורטים ההבדלים בין מה שמדווח ב-API לבין אופן החישוב של המדד.

ההבדלים בין המדד לבין ה-API

  • ה-API ישלח רשומות largest-contentful-paint לדפים שנטענו בכרטיסייה ברקע, אבל צריך להתעלם מהדפים האלה כשמחשבים את LCP.
  • ה-API ימשיך לשלוח רשומות largest-contentful-paint אחרי שהדף יועבר לרקע, אבל צריך להתעלם מהרשומות האלה כשמחשבים את LCP (אפשר להביא בחשבון רכיבים רק אם הדף היה בחזית כל הזמן).
  • ה-API לא מדווח על רשומות largest-contentful-paint כשהדף משוחזר מהמטמון של 'הקודם'/'הבא', אבל צריך למדוד את LCP במקרים האלה כי המשתמשים חווים אותם כביקור נפרד בדף.
  • ה-API לא מתייחס לרכיבים שבתוך מסגרות iframe, אבל המדד כן מתייחס אליהם כפי שהם חלק מחוויית המשתמש בדף. בדפים עם LCP בתוך iframe – לדוגמה, תמונת פוסטרים בסרטון מוטמע – ההבדל יופיע בין CrUX לבין RUM. כדי למדוד את LCP בצורה נכונה, כדאי להביא בחשבון את הגורמים האלה. תמונות משנה יכולות להשתמש ב-API כדי לדווח על רשומות largest-contentful-paint שלהן למסגרת ההורה לצורך צבירה.
  • ה-API מודד את LCP מתחילת הניווט, אבל בדפים שעברו רינדור מראש צריך למדוד את LCP מ-activationStart, כי זהו הזמן של LCP כפי שהמשתמש חווה אותו.

במקום לזכור את כל ההבדלים העדינים האלה, מפתחים יכולים להשתמש בספריית JavaScript של web-vitals כדי למדוד את LCP, והיא מטפלת בהבדלים האלה בשבילכם (במקרים שבהם זה אפשרי – שימו לב שהבעיה של iframe לא מכוסה):

import {onLCP} from 'web-vitals';

// Measure and log LCP as soon as it's available.
onLCP(console.log);

בקוד המקור של onLCP() תמצאו דוגמה מלאה למדידת LCP ב-JavaScript.

מה קורה אם האלמנט הגדול ביותר הוא לא החשוב ביותר?

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

איך לשפר את מדד ה-LCP

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

מקורות מידע נוספים

יומן שינויים

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

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

אם יש לכם משוב לגבי המדדים האלה, אתם יכולים לשלוח אותו לקבוצת Google‏ web-vitals-feedback.