Largest Contentful Paint (LCP)

תמיכה בדפדפן

  • 77
  • 79
  • 122
  • x

מקור

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

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

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

מה זה LCP?

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

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

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

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

אילו אלמנטים נלקחים בחשבון?

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

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

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

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

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

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

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

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

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

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

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

מתי מתבצע דיווח על מדד LCP?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

דוגמאות

לפניכם כמה דוגמאות למקרים שבהם הצגת התוכן הכי גדול (LCP) מופיעה במספר אתרים פופולריים:

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

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

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

ציר הזמן Largest Contentful Paint (LCP) בכתובת instagram.com
ציר זמן LCP מ-instagram.com.
ציר הזמן Largest Contentful Paint (LCP) מ-google.com
ציר זמן LCP מ-google.com.

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

איך מודדים LCP

ניתן למדוד את ה-LCP במעבדה או בשדה. הוא זמין בכלים הבאים:

כלי שדה

כלי מעבדה

מדידת 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 תואם לזמן ה-LCP כפי שהמשתמש חווה.

במקום לזכור את כל ההבדלים הקלים האלה, מפתחים יכולים להשתמש בספריית web-vitals JavaScript כדי למדוד 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 בשטח ובשימוש בנתונים ממעבדה כדי להתעמק בנתונים ולבצע אופטימיזציה שלהם.

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

יומן שינויים

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

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

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