Images are a big part of many applications, and can be a major contributor to application performance problems, including low Core Web Vitals scores.
Image optimization can be a complex topic, but Angular handles most of it for you, with the NgOptimizedImage
directive. In this activity, you'll learn how to use NgOptimizedImage
to ensure your images are loaded efficiently.
-
Import the NgOptimizedImage directive
In order to leverage the
NgOptimizedImage
directive, first import it from the@angular/common
library and add it to the componentimports
array.import { NgOptimizedImage } from '@angular/common';@Component({ standalone: true, imports: [NgOptimizedImage], ...})
-
Update the src attribute to be ngSrc
To enable the
NgOptimizedImage
directive, swap out thesrc
attribute forngSrc
. This applies for both static image sources (i.e.,src
) and dynamic image sources (i.e.,[src]
).import { NgOptimizedImage } from '@angular/common';@Component({ standalone: true, template: ` ... <li> Static Image: <img ngSrc="/assets/logo.svg" alt="Angular logo" width="32" height="32" /> </li> <li> Dynamic Image: <img [ngSrc]="logoUrl" [alt]="logoAlt" width="32" height="32" /> </li> ... `, imports: [NgOptimizedImage],})
-
Add width and height attributes
Note that in the above code example, each image has both
width
andheight
attributes. In order to prevent layout shift, theNgOptimizedImage
directive requires both size attributes on each image.In situations where you can't or don't want to specify a static
height
andwidth
for images, you can use thefill
attribute to tell the image to act like a "background image", filling its containing element:<div class="image-container"> //Container div has 'position: "relative"' <img ngSrc="www.example.com/image.png" fill /></div>
Note: For the
fill
image to render properly, its parent element must be styled withposition: "relative"
,position: "fixed"
, orposition: "absolute"
. -
Prioritize important images
One of the most important optimizations for loading performance is to prioritize any image which might be the "LCP element", which is the largest on-screen graphical element when the page loads. To optimize your loading times, make sure to add the
priority
attribute to your "hero image" or any other images that you think could be an LCP element.<img ngSrc="www.example.com/image.png" height="600" width="800" priority />
-
Optional: Use an image loader
NgOptimizedImage
allows you to specify an image loader, which tells the directive how to format URLs for your images. Using a loader allows you to define your images with short, relative URLs:providers: [ provideImgixLoader('https://my.base.url/'),]
Final URL will be 'https://my.base.url/image.png'
<img ngSrc="image.png" height="600" width="800" />
Image loaders are for more than just convenience--they allow you to use the full capabilities of
NgOptimizedImage
. Learn more about these optimizations and the built-in loaders for popular CDNs here.
By adding this directive to your workflow, your images are now loading using best practices with the help of Angular 🎉
If you would like to learn more, check out the documentation for NgOptimizedImage
. Keep up the great work and let's learn about routing next.