בעיות עיקריות בביצועים

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

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

דחיית בקשות לתמונה

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

<img src="image.jpg" loading="lazy" alt="…">

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

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

עם זאת, יש מלכוד: דחיית הבקשות האלה פירושה שלא לנצל את היתרונות של הדפדפנים תהליכים אופטימליים לשליחת בקשות תמונות מוקדם ככל האפשר. אם נעשה שימוש בפונקציה loading="lazy" ברכיבי img לקראת החלק העליון של הפריסה, ולכן סביר יותר להיות באזור התצוגה של המשתמש כשהוא נטען לראשונה — תמונות אלה עלולות לגרום למשתמש הקצה לאט יותר.

עדיפות אחזור

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

סביר להניח שאתם מודעים לדפדפנים גישות בסיסיות לאחזור עדיפות: לדוגמה, בקשה לקובץ CSS חיצוני ב-<head> של מסמך נחשבת חיונית מספיק כדי לחסום את העיבוד, ולעומת זאת בקשה לקבלת קובץ קובץ JavaScript חיצוני שנמצא מעל </body> יידחה עד לסיום העיבוד. אם הערך של מאפיין loading ב-<img> הוא 'lazy', בקשת התמונה המשויכת תידחה עד שהדפדפן יקבע שהיא תוצג למשתמש. אחרת, אותה תמונה תהיה בעדיפות גבוהה יותר מכל תמונה אחרת בדף.

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

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

מדידת ההשפעה של תמונות

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

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

Cumulative Layout Shift ‏(CLS)

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

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

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

אם אתם עובדים בממשק הקצה כבר כמה שנים, כדאי שתכירו את המאפיינים width ו-height ב-<img>: לפני האימוץ הרחב של שירות CSS, אלה היו הדרך היחידה לשלוט בגודל התמונה.

<img src="image.jpg" height="200" width="400" alt="…">

לא השתמשתם במאפיינים האלה כדי לשמור על הפרדה בין חששות הסגנון שלנו לתגי העיצוב שלנו, במיוחד כי הם רספונסיביים. היה צורך לציין מידה מבוססת אחוזים באמצעות CSS. בימים הראשונים של עיצוב האתר הרספונסיבי, "הסר מאפייני width ו-height שאינם בשימוש היה ייעוץ נפוץ, כמו הערכים שציינו בשירות ה-CSS שלנו – max-width: 100% וגם height: auto — תשנה אותן.

<img src="image.jpg" alt="…">
img {
  max-width: 100%;
  height: auto;
}

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

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

ככלל, צריך תמיד להשתמש במאפייני height ו-width ב-<img>, עם ערכים שתואמים לגודל הפנימי של מקור התמונה – כך כל עוד חשוב לוודא שציינתם height: auto לצד max-width: 100% כדי לעקוף את הגובה ממאפיין ה-HTML.

<img src="image.jpg" height="200" width="400" alt="…">
img {
  max-width: 100%;
  height: auto;
}

שימוש במאפיינים width ו-height ברכיבי <img> יעזור לך להימנע מציון CLS גבוה בגלל תמונות.

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

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

Largest Contentful Paint ‏(LCP)

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

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

לתפיסת המשתמש שתועדה על ידי LCP יש השפעה ישירה על חוויית המשתמש. ניסוי שבוצע על ידי Vodafone רק בשנה שעברה גילו ששיפור של 31% ב-LCP לא הניב רק 8% יותר מכירות – תוצאה חזקה בפני עצמה – אלא שעלייה של 15% במספר המשתמשים הכולל שיפור במספר המבקרים שהפכו ללקוחות פוטנציאליים ('שיעור מבקרים ללידים') ושיפור של 11% במספר המשתמשים אנשים שביקרו בעגלת הקניות שלהם ("שיעור עגלת הקניות לביקור").

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

LCP מודגש במסוף של דף web.dev

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

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

סיכום

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

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

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