לפני קצת יותר משנה, צוות Chrome Aurora השיק את ההוראה NgOptimizedImage של Angular. ההנחיה מתמקדת בעיקר בשיפור הביצועים, כפי שנמדדים לפי מדדי Core Web Vitals. ה-API הזה מקבץ שיטות מומלצות ואופטימיזציות נפוצות של תמונות ב-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 Vitals).
החיסרון של המאפיין srcset
הוא שהטמעתו יכולה להיות מסורבלת. כשמעיינים בערכים של srcset
באופן ידני, צריך להוסיף כמה שורות של רכיבי Markup לכל רכיב תמונה באפליקציה, יחד עם כמה כתובות URL בהתאמה אישית לכל srcset
. בנוסף, צריך להחליט על קבוצה של נקודות עצירה. זהו תהליך מורכב, כי הנקודות האלה יכולות לייצג גם את צפיפות המסך וגם את גדלי חלון התצוגה של מכשירים נפוצים.
לכן, הוספת יצירה אוטומטית של 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 רספונסיבי שכולל נקודות עצירה רבות למכשירים ולגדלים נפוצים של תמונות, באמצעות רשימת ברירת המחדל הזו של נקודות עצירה:
[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 של התמונות של האפליקציה. הספרייה כוללת קבוצה של מערכי טעינה מובנים ל-CDNs נפוצים. אנחנו גם מספקים אפשרות להשתמש במטענים מותאמים אישית, שמאפשרים לשלב את 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. אם לא משתמשים בהנחיה באפליקציה, לא תקבלו הנחיות לגבי בעיות בביצועים של תמונות.
ב-Angular 17, אנחנו מרחיבים את היקף ההנחיות לגבי ביצועי תמונות כך שיכללו את כל האפליקציות של Angular. עכשיו, אם נזהה דפוסי תמונות שאנחנו יודעים שהם שגיאות שמשפיעות לרעה על הביצועים, כמו טעינת פריטים בזמן אמת (lazy-loading) של התמונה של LCP או הורדה של קובץ גדול מדי לדף, נודיע לכם על כך, גם אם אתם לא משתמשים ב-NgOptimizedImage.
ביצועי התמונות חשובים לכל האפליקציות, ואנחנו שמחים להמשיך לפתח אמצעי הגנה שיעזרו למנוע טעויות נפוצות באפליקציות Angular.
ומה בעתיד?
אנחנו כבר עובדים במרץ על פיתוח הקבוצה הבאה של התכונות ל-NgOptimizedImage. ביצועי התמונות עדיין נמצאים בראש סדר העדיפויות שלנו, אבל אנחנו רוצים גם להוסיף תכונות שמשפרות את חוויית הפיתוח, כדי לוודא ש-NgOptimizedImage תישאר אפשרות אטרקטיבית להכללת תמונות באפליקציות Angular.
אחד מהפיצ'רים שחשובים לנו במיוחד הוא placeholders של תמונות. בדרך כלל משתמשים בהן כדי לשפר את הטעינה של תמונות באפליקציות אינטרנט, אבל אם מטמיעים אותן בצורה שגויה, הן עלולות לפגוע בביצועים. אנחנו מקווים שנוכל ליצור מערכת של placeholder לתמונות שמתמקדת בביצועים ב-NgOptimizedImage. כדאי לעקוב אחרי העדכונים בבלוג שלנו.