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

Alex Castle
Alex Castle

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

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

תכונות חדשות

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

מצב מילוי

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

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

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

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

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

לכן, ההוספה של יצירה אוטומטית של srcset להנחיה NgOptimizedImage הייתה ציון דרך משמעותי אחרי ההשקה. בזכות התוספת הזו, כל אפליקציה שמשתמשת ב-CDN שתומך בשינוי גודל של תמונות יכולה להתווסף באופן אוטומטי ל-srcsets מלאים, ניתנים להתאמה אישית, לכל תמונה שנוצרה באמצעות ההוראה 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 רספונסיבי שכולל נקודות עצירה (breakset) לגדלים נפוצים של מכשירים ותמונות, תוך שימוש ברשימת נקודות העצירה (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.

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

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

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

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

מבט לעתיד

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

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