מה חדש בהנחיה Angular NgOptimizedImage

קאסל אלכס
ארמון אלכס

לפני קצת יותר משנה, צוות Chrome Aurora השיק את ההנחיה של Anngular NgOptimizedImage. ההנחיה מתמקדת בעיקר בשיפור ביצועים, כפי שנמדד באמצעות המדדים של מדדי ליבה לבדיקת חוויית המשתמש באתר. היא משלבת שיטות מומלצות ואופטימיזציות נפוצות של תמונות ב-API שמוצג למשתמש ולא הרבה יותר מורכב מאלמנט <img> רגיל.

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

תכונות חדשות

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

מצב מילוי

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

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

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

במצב מילוי נעשה שימוש ב-NgOptimizedImage כחלופה בעלת ביצועים טובים יותר לנכס ה-CSS background-image. יש למקם תמונה בתוך ה-<div> או בתוך רכיב אחר שהיה אמור להיות מעוצב עם background-image, ולאחר מכן להפעיל את מצב המילוי, כפי שמוצג בדוגמת הקוד הקודמת. ניתן להשתמש במאפייני ה-CSS object-fit ו-object-position ב-<div> כדי לקבוע את מיקום התמונה ברקע.

// Height and width are required
<img ngSrc="example.com" height="300" width="400">

// Unless you use fill mode!
<div style="width: 100vw; height: 50em; position: relative">
  <img ngSrc="example.com" fill>
</div>

יצירת Srcset

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

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

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

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

<img src="www.example.com/image.png" srcset="www.example.com/image.png?w=400 1x, www.example.com/image.png?w=800 2x" >

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

מצד שני, אם תכללו את המאפיין sizes, המערכת של NgOptimizedImage תיצור קבוצת srcset רספונסיבית שכוללת נקודות עצירה בגדלים נפוצים רבים של מכשירים ותמונות, על סמך רשימת ברירת המחדל הזו של נקודות עצירה (breakpoint):

[16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]

יצירת חיבור מראש

כדי לשפר את מדד ה-LCP, חשוב לצמצם את הזמן שהמשתמשים מקדישים להורדת התמונה מסוג LCP. בקטע הקודם הסברת איך העברת קובצי תמונות קטנים יותר בעזרת srcset יכולה לעזור, אבל אופטימיזציה חשובה לא פחות היא להתחיל בהעברה בהקדם האפשרי. אחת הדרכים לעשות את זה היא להשתמש בתגי link rel="preconnect" כדי לזרז את החיבור לדומיין התמונות.

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

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

תמיכה מתקדמת למטענים מותאמים אישית

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

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

הדוגמה הבאה מראה איך כלי טעינה פשוט בהתאמה אישית יכול להשתמש ב-API של loaderParams כדי לבחור בין שני דומיינים חלופיים של תמונות:

const myCustomLoader = (config: ImageLoaderConfig) => {
  if (config.loaderParams?.alternateDomain) {
    return `https://alternate.domain.com/images/${config.src}`
  }
  return `https://primary.domain.com/images/${config.src}`;
};

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

הנחיות מורחבות לביצועי תמונות

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

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

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

מבט לעתיד

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

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