איך מזהים שינויים בפריסה ומתקנים אותם
בחלק הראשון של המאמר נסביר על כלים לניפוי באגים של שינויים בפריסה, ובחלק השני נסביר על תהליך החשיבה שצריך להשתמש בו כדי לזהות את הסיבה לשינוי בפריסה.
כלים
Layout Instability API
Layout Instability API הוא המנגנון בדפדפן למדידת שינויים בפריסה ולדיווח עליהם. כל הכלים לניפוי באגים של שינויים בפריסה, כולל DevTools, מבוססים בסופו של דבר על Layout Instability API. עם זאת, השימוש ישירות ב-Layout Instability API הוא כלי ניפוי באגים חזק בזכות הגמישות שלו.
שימוש
אותו קטע קוד שמודד את Cumulative Layout Shift (CLS) יכול לשמש גם לניפוי באגים של שינויים בפריסת הדף. קטע הקוד הבא מתעד במסוף מידע על שינויים בפריסה. עיון ביומן הזה יספק לכם מידע על המיקום, המועד והאופן שבהם התרחשה שינוי בפריסת האתר.
let cls = 0;
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
if (!entry.hadRecentInput) {
cls += entry.value;
console.log('Current CLS value:', cls, entry);
}
}
}).observe({type: 'layout-shift', buffered: true});
כשמריצים את הסקריפט הזה, חשוב לזכור:
- האפשרות
buffered: true
מציינת ש-PerformanceObserver
צריך לבדוק במאגר הרשומות של הביצועים בדפדפן אם יש רשומות של ביצועים שנוצרו לפני האימות של המנטר. כתוצאה מכך, הערך שלPerformanceObserver
יכלול דיווח על שינויים בפריסה שהתרחשו גם לפני וגם אחרי שהוא הופעל. חשוב לזכור זאת כשבודקים את יומני המסוף. אם יש לכם גידול משמעותי במספר השינויים הראשונים בתצוגה, יכול להיות שמדובר בבקשות דיווח שנצברו ולא באירועים רבים של שינויים בתצוגה. - כדי לא להשפיע על הביצועים, ה-
PerformanceObserver
ממתין עד שהשרשור הראשי יהיה במצב חוסר פעילות כדי לדווח על שינויים בפריסה. כתוצאה מכך, בהתאם לעומס על החוט הראשי, יכול להיות עיכוב קל בין מועד השינוי של הפריסה לבין הרגע שבו הוא מתועד ביומן במסוף. - הסקריפט הזה מתעלם משינויי פריסה שהתרחשו תוך 500 אלפיות השנייה ממועד הקלט של המשתמש, ולכן הם לא נספרים במדד CLS.
הדיווח על מידע לגבי שינויים בפריסה מתבצע באמצעות שילוב של שני ממשקי API: הממשקים LayoutShift
ו-LayoutShiftAttribution
. כל אחד מהממשקים האלה מוסבר בהרחבה בקטעים הבאים.
LayoutShift
כל שינוי בפריסה מדווח באמצעות הממשק LayoutShift
. התוכן של רשומה נראה כך:
duration: 0
entryType: "layout-shift"
hadRecentInput: false
lastInputTime: 0
name: ""
sources: (3) [LayoutShiftAttribution, LayoutShiftAttribution, LayoutShiftAttribution]
startTime: 11317.934999999125
value: 0.17508567530168798
הרשומה שלמעלה מציינת שינוי בפריסה במהלכו שלושה רכיבי DOM השתנו מיקום. הציון של שינוי הפריסה הזה היה 0.175
.
אלה המאפיינים של מכונה של LayoutShift
שרלוונטיים ביותר לניפוי באגים של שינויים בפריסה:
נכס | תיאור |
---|---|
sources |
בנכס sources מפורטים רכיבי ה-DOM שהועברו במהלך שינוי הפריסה. המערך הזה יכול להכיל עד חמישה מקורות. אם יש יותר מחמישה רכיבים שמושפעים משינוי הפריסה, המערכת מדווחת על חמשת המקורות הגדולים ביותר (לפי ההשפעה על יציבות הפריסה) של שינוי הפריסה. המידע הזה מדווח באמצעות הממשק LayoutShiftAttribution (מפורט בהמשך). |
value |
הנכס value מדווח על הציון של שינוי הפריסה של שינוי פריסה מסוים. |
hadRecentInput |
המאפיין hadRecentInput מציין אם חל שינוי בפריסה תוך 500 אלפיות השנייה ממועד הקלט של המשתמש. |
startTime |
המאפיין startTime מציין מתי התרחש שינוי בפריסת האתר. הערך של startTime מצוין באלפיות שנייה ונמדד ביחס לזמן שבו התחיל תהליך טעינת הדף. |
duration |
המאפיין duration תמיד יוגדר כ-0 . הנכס הזה עובר בירושה מהממשק PerformanceEntry (הממשק LayoutShift הוא הרחבה של הממשק PerformanceEntry ). עם זאת, המושג 'משך זמן' לא חל על אירועי שינוי פריסה, ולכן הוא מוגדר כ-0 . מידע על הממשק PerformanceEntry זמין במפרט. |
LayoutShiftAttribution
הממשק LayoutShiftAttribution
מתאר העברה יחידה של רכיב DOM יחיד. אם כמה אלמנטים זזים במהלך שינוי של הפריסה, המאפיין sources
מכיל כמה רשומות.
לדוגמה, ה-JSON שבהמשך תואם לשינוי פריסה עם מקור אחד: השינוי כלפי מטה של רכיב ה-DOM <div id='banner'>
מ-y: 76
ל-y:246
.
// ...
"sources": [
{
"node": "div#banner",
"previousRect": {
"x": 311,
"y": 76,
"width": 4,
"height": 18,
"top": 76,
"right": 315,
"bottom": 94,
"left": 311
},
"currentRect": {
"x": 311,
"y": 246,
"width": 4,
"height": 18,
"top": 246,
"right": 315,
"bottom": 264,
"left": 311
}
}
]
המאפיין node
מזהה את רכיב ה-HTML שהוזז. כשמעבירים את העכבר מעל המאפיין הזה ב-DevTools, רכיב הדף התואם מודגש.
המאפיינים previousRect
ו-currentRect
מדווחים על הגודל והמיקום של הצומת.
- הקואורדינטות
x
ו-y
מדווחות על קואורדינטת ה-x ועל קואורדינטת ה-y של הפינה הימנית העליונה של הרכיב, בהתאמה - המאפיינים
width
ו-height
מדווחים על הרוחב והגובה של האלמנט, בהתאמה. - המאפיינים
top
,right
,bottom
ו-left
מדווחים על ערכי הקואורדינטות x או y שתואמים לקצה הנתון של הרכיב. במילים אחרות, הערך שלtop
שווה ל-y
, והערך שלbottom
שווה ל-y+height
.
אם כל המאפיינים של previousRect
מוגדרים כ-0, המשמעות היא שהרכיב עבר לתצוגה. אם כל המאפיינים של currentRect
מוגדרים ל-0, המשמעות היא שהרכיב השתנה מחוץ לתצוגה.
אחד הדברים החשובים ביותר להבין כשמפרשים את הפלט הזה הוא שהרכיבים שמפורטים בתור מקורות הם הרכיבים שהשתנו במהלך השינוי של הפריסה. עם זאת, יכול להיות שהרכיבים האלה קשורים באופן עקיף בלבד ל'סיבת השורש' של חוסר היציבות בפריסה. ריכזנו כאן כמה דוגמאות.
דוגמה מס' 1
שינוי הפריסה הזה ידווח עם מקור אחד: רכיב ב'. עם זאת, סיבת השורש של שינוי הפריסה הזה היא השינוי בגודל של רכיב א'.
דוגמה 2
בדוגמה הזו, השינוי בפריסה ידווח עם שני מקורות: רכיב א' ורכיב ב'. שורש הבעיה של שינוי הפריסה הזה הוא השינוי במיקום של רכיב א'.
דוגמה מס' 3
השינוי בפריסת הדף בדוגמה הזו ידווח עם מקור אחד: רכיב ב'. שינוי המיקום של רכיב ב' הוביל לשינוי הפריסה הזה.
דוגמה 4
למרות שרכיב ב' משתנה בגודל, אין שינוי פריסה בדוגמה הזו.
דוגמה לדיווח על שינויים ב-DOM באמצעות Layout Instability API
כלי פיתוח
חלונית הביצועים
בחלונית Experience (חוויית המשתמש) שבחלונית Performance (ביצועים) של DevTools מוצגים כל השינויים בפריסה שמתרחשים במהלך מעקב ביצועים נתון – גם אם הם מתרחשים תוך 500 אלפיות השנייה מממשק המשתמש, ולכן לא נספרים במדד CLS. אם מעבירים את העכבר מעל שינוי פריסה מסוים בחלונית חוויית השימוש, רכיב ה-DOM מושפע מודגש.
כדי להציג מידע נוסף על שינויי הפריסה, לוחצים על שינויי הפריסה ואז פותחים את התיבה סיכום. שינויים במימדים של הרכיב מפורטים בפורמט [width, height]
, ושינויים במיקום של הרכיב מפורטים בפורמט [x,y]
. המאפיין Had recent input מציין אם שינוי בפריסה התרחש תוך 500 אלפיות השנייה ממועד האינטראקציה של המשתמש.
כדי לקבל מידע על משך הזמן של שינוי הפריסה, פותחים את הכרטיסייה יומן האירועים. אפשר גם לקבל הערכה לגבי משך הזמן של שינוי הפריסה על ידי בדיקת האורך של המלבן האדום של שינוי הפריסה בחלונית חוויית השימוש.
מידע נוסף על השימוש בחלונית ביצועים זמין במאמר חומר עזר בנושא ניתוח ביצועים.
הדגשת האזורים שזזו בפריסה
הדגשת אזורים שהוזזו בפריסה יכולה להיות שיטה שימושית שבעזרתה תוכלו לקבל במהירות ובקלות מידע על המיקום והתזמון של השינויים בפריסה שמתרחשים בדף.
כדי להפעיל את התכונה 'אזורים של שינויי פריסה' בכלי הפיתוח, עוברים אל הגדרות > כלים נוספים > עיבוד > אזורים של שינויי פריסה ולאחר מכן מרעננים את הדף שרוצים לנפות בו באגים. אזורים שהפריסה שלהם השתנתה יסומנו למשך זמן קצר בצבע סגול.
תהליך החשיבה לזיהוי הסיבה לשינויים בפריסה
אפשר להשתמש בשלבים הבאים כדי לזהות את הגורם לשינויים בפריסה, ללא קשר למועד שבו הם מתרחשים או לאופן שבו הם מתרחשים. אפשר להוסיף לשלבים האלה את הפעלת Lighthouse. עם זאת, חשוב לזכור ש-Lighthouse יכול לזהות רק שינויים בפריסת הדף שהתרחשו במהלך טעינת הדף הראשונית. בנוסף, Lighthouse יכול לספק הצעות רק לגבי חלק מהסיבות לשינויים בפריסה – לדוגמה, רכיבי תמונה ללא רוחב ואורך מפורשים.
זיהוי הסיבה לשינוי בפריסה
שינויים בפריסה יכולים להיגרם מהאירועים הבאים:
- שינויים במיקום של רכיב DOM
- שינויים במאפיינים של רכיב DOM
- הוספה או הסרה של רכיב DOM
- אנימציות שמפעילות פריסה
באופן ספציפי, רכיב ה-DOM שמופיע מיד לפני הרכיב שעבר שינוי הוא הרכיב שסביר להניח שהוא 'גורם' לשינוי הפריסה. לכן, כשבודקים למה התרחש שינוי בפריסה, כדאי לשקול את הגורמים הבאים:
- האם המיקום או המימדים של הרכיב הקודם השתנו?
- האם רכיב DOM הוכנס או הוסר לפני הרכיב שהוזז?
- האם המיקום של הרכיב שהוזז השתנה באופן מפורש?
אם הרכיב הקודם לא גרם לשינוי הפריסה, ממשיכים לחפש רכיבים אחרים שקודמים לרכיב הזה או שנמצאים בסביבתו.
בנוסף, הכיוון והמרחק של שינוי הפריסה יכולים לספק רמזים לגבי הגורם הבסיסי. לדוגמה, לרוב, אם יש הזזה גדולה כלפי מטה, סימן שהוסף רכיב DOM. לעומת זאת, לרוב, אם יש הזזה של 1px או 2px בפריסה, סימן שהופעלו סגנונות CSS מתנגשים או שהתבצעה טעינה והפעלה של גופן אינטרנט.
אלה כמה מההתנהגויות הספציפיות שגורמות לאירועים של שינויים בפריסה בתדירות הגבוהה ביותר:
שינויים במיקום של רכיב (שאינם נובעים מהתנועה של רכיב אחר)
סוג השינוי הזה הוא בדרך כלל תוצאה של:
- גיליונות סגנונות שנטענים מאוחר או מחליפים סגנונות שהוגדרו בעבר.
- אנימציות ואפקטים של מעבר.
שינויים במאפייני המימדים של רכיב
סוג השינוי הזה הוא בדרך כלל תוצאה של:
- גיליונות סגנונות שנטענים מאוחר או מחליפים סגנונות שהוגדרו בעבר.
- תמונות ופריטי iframe ללא מאפייני
width
ו-height
שנטענים אחרי שה'חריץ' שלהם עבר עיבוד. - בלוקים של טקסט ללא מאפייני
width
אוheight
שמבצעים החלפה של גופנים אחרי שהטקסט עבר עיבוד.
הוספה או הסרה של רכיבי DOM
בדרך כלל, הסיבות לכך הן:
- הטמעת מודעות ופריטים מוטמעים אחרים של צד שלישי.
- הטמעת באנר, התראות ותיבות דו-שיח.
- גלילה אינסופית ודפוסי UX אחרים שמאפשרים טעינה של תוכן נוסף מעל התוכן הקיים.
אנימציות שמפעילות פריסה
אפקטים מסוימים של אנימציה יכולים להפעיל את הפריסה. דוגמה נפוצה לכך היא כשרכיבי DOM 'מתנפשים' על ידי הגדלת מאפיינים כמו top
או left
, במקום להשתמש במאפיין transform
של CSS. מידע נוסף זמין במאמר איך יוצרים אנימציות CSS עם ביצועים גבוהים.
איך משחזרים שינויי פריסה
אי אפשר לתקן שינויים בפריסת האתר שלא ניתן לשחזר. אחת הדרכים הפשוטות והיעילות ביותר להבין טוב יותר את יציבות הפריסה של האתר היא להקדיש 5-10 דקות לאינטראקציה עם האתר במטרה לגרום לשינויים בפריסה. חשוב להשאיר את המסוף פתוח בזמן ביצוע הפעולות האלה, ולהשתמש ב-Layout Instability API כדי לדווח על שינויים בפריסה.
אם קשה לאתר שינויים בפריסה, כדאי לחזור על התרגיל הזה במכשירים שונים ובמהירויות חיבור שונות. במיוחד, שימוש במהירות חיבור איטית יותר יכול לעזור לכם לזהות בקלות שינויים בפריסה. בנוסף, תוכלו להשתמש בהצהרה debugger
כדי להקל על הדפדוף בין שינויי הפריסה.
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntries()) {
if (!entry.hadRecentInput) {
cls += entry.value;
debugger;
console.log('Current CLS value:', cls, entry);
}
}
}).observe({type: 'layout-shift', buffered: true});
לבסוף, אם נתקלתם בבעיות בפריסת האתר שלא ניתן לשחזר בתהליך הפיתוח, מומלץ להשתמש ב-Layout Instability API בשילוב עם כלי הרישום ביומן של חזית האתר שבחרתם כדי לאסוף מידע נוסף על הבעיות האלה. קוד לדוגמה למעקב אחרי הרכיב הגדול ביותר שעבר שינוי בדף