יולי 26, 2020

LCP – טעינה והצגה של רכיב התוכן הגדול ביותר

LCP – טעינה והצגה של רכיב התוכן הגדול ביותר

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

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

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

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

מה זה LCP?

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

מה נחשב לציון LCP טוב?

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

אילו רכיבים בדף נלקחים בחשבון בתהליך החישוב?

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

·      רכיבי תמונה הנמצאים בתגית <img>

·      רכיבי תמונה <img> בתוך <svg>

·      רכיבי סרטון בתוך <video> (כאשר נעשה שימוש בתמונה הראשית של הסרטון)

·      רכיבי תמונת הרקע הנטענים באמצעות פונקציית url() – זאת בניגוד לאפשרות הקיימת בתוך ה- CSS Gradient.

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

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

כיצד נקבע גודל הרכיב בדף?

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

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

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

באופן גורף עבור כל הרכיבים בדף – נתוניPadding  (מרווח), Margin (שוליים) ו-Border (מסגרת סביב הרכיב) בקובץ העיצוב (CSS) לא ישוקללו.

________________________________________________

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

מתי ההצגה של רכיב התוכן הגדול ביותר (LCP) מדווחת?

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

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

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

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

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

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

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

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

זמן הטעינה מול זמן העיבוד

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

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

כיצד מטופלים פריסת הרכיבים בדף וגודלם?

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

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

בכל מקרה (כפי שהוזכר לעיל), הרכיבים שהוסרו מה-DOM לא ילקחו בחשבון אם מקור התמונה שלהם השתנה.

דוגמאות

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

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

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

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

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

כיצד למדוד LCP?

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

מדידה בתנאי שטח

·       דו"ח חוויית המשתמש של כרום – Chrome User Experience Report

·       תובנות PageSpeed – PageSpeed Insights

·       דו"ח מדדי הליבה ברשת – Search Console (Core Web Vitals report)

מדידה בתנאי מעבדה

·       כלי הפיתוח של כרום – Chrome DevTools

·       פלטפורמת המגדלור – Lighthouse

·       אתר WebPageTest

מדידת LCP באמצעות ג'אווה סקריפט

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

import {getLCP} from 'web-vitals';

// Measure and log the current LCP value,
// any time it's ready to be reported.
getLCP(console.log);

כדי לחשב בצורה ידנית את הLCP, ניתן להשתמש ב-API של Largest Contentful Paint. הדוגמה הבאה מציגה כיצד ניתן ליצור מופע של PerformanceObserver שיאזין לכל הרשומות של Largest-Contentful-paint ויתעד את ערך ה LCP לתוך הקונסול: (יש להעתיק את הקוד המופיע במקור).

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

מה אם הרכיב הגדול ביותר בדף אינו הרכיב המשמעותי ביותר?

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

כיצד ניתן לבצע אופטימיזציה ל-LCP?

LCP מושפע בעיקר מארבעה גורמים:

·       זמן תגובה ארוך ואיטי של השרת

·       ג'אווה סקריפט וקובץ סטיילינג (CSS) המעקבים או מונעים את עיבוד הדף

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

·       עיבוד בצד הלקוח