The NgOptimizedImage
directive is available for developer preview.
It's ready for you to try, but it might change before it is stable.
The NgOptimizedImage
directive makes it easy to adopt performance best practices for loading images.
The NgOptimizedImage
directive ensures that the loading of the Largest Contentful Paint image is prioritized by:
- Automatically setting the
fetchpriority
attribute on the<img>
tag - Lazy loading other images by default
- Asserting that there is a corresponding preconnect link tag in the document head
In addition to optimizing the loading of the LCP image, NgOptimizedImage
enforces a number of image best practices:
- Using image URLs to apply image optimizations
- Requires that
width
andheight
are set - Warns if
width
orheight
have been set incorrectly - Warns if the image will be visually distorted when rendered
You will need to import the directive into your application. In addition, you will need to set up an image loader. These steps are explained in the Setting up NgOptimizedImage
tutorial.
To activate the NgOptimizedImage
directive, replace your image's src
attribute with ngSrc
.
<img ngSrc="cat.jpg" width="400" height="200">
The built-in third-party loaders prepend a shared base URL to src
. If you're using one of these loaders (or any other loader that does this), make sure to omit the shared base URL path from src
to prevent unnecessary duplication.
You must also set the width
and height
attributes. This is done to prevent image-related layout shifts. The width
and height
attributes should reflect the intrinsic size of the image. During development, the NgOptimizedImage
warns if it detects that the width
and height
attributes have been set incorrectly.
Always mark the LCP image on your page as priority
to prioritize its loading.
<img ngSrc="cat.jpg" width="400" height="200" priority>
Marking an image as priority
applies the following optimizations:
- Sets
fetchpriority=high
(read more about priority hints here) - Sets
loading=eager
(read more about native lazy loading here)
Angular displays a warning during development if the LCP element is an image that does not have the priority
attribute. A page’s LCP element can vary based on a number of factors - such as the dimensions of a user's screen. A page may have multiple images that should be marked priority
. See CSS for Web Vitals for more details.
You can add a preconnect
resource hint for your image origin to ensure that the LCP image loads as quickly as possible. Always put resource hints in the <head>
of the document.
<link rel="preconnect" href="https://my.cdn.origin" />
By default, if you use a loader for a third-party image service, the NgOptimizedImage
directive will warn during development if it detects that there is no preconnect
resource hint for the origin that serves the LCP image.
To disable these warnings, add {ensurePreconnect: false}
to the arguments passed to the provider factory for your chosen image service:
providers: [ provideImgixLoader('https://my.base.url', {ensurePreconnect: false}) ],
In cases where you want to have an image fill a containing element, you can use the fill
attribute. This is often useful when you want to achieve a "background image" behavior, or when you don't know the exact width and height of your image.
When you add the fill
attribute to your image, you do not need and should not include a width
and height
, as in this example:
<img ngSrc="cat.jpg" fill>
Depending on the image's styling, adding width
and height
attributes may cause the image to render differently. NgOptimizedImage
warns you if your image styling renders the image at a distorted aspect ratio.
You can typically fix this by adding height: auto
or width: auto
to your image styles. For more information, see the web.dev article on the <img>
tag.
Defining a srcset
attribute ensures that the browser requests an image at the right size for your user's viewport, so it doesn't waste time downloading an image that's too large. 'NgOptimizedImage' generates an appropriate srcset
for the image, based on the presence and value of the sizes
attribute on the image tag.
If your image should be "fixed" in size (i.e. the same size across devices, except for pixel density), there is no need to set a sizes
attribute. A srcset
can be generated automatically from the image's width and height attributes with no further input required.
Example srcset generated: <img ... srcset="image-400w.jpg 1x, image-800w.jpg 2x">
If your image should be responsive (i.e. grow and shrink according to viewport size), then you will need to define a sizes
attribute to generate the srcset
.
If you haven't used sizes
before, a good place to start is to set it based on viewport width. For example, if your CSS causes the image to fill 100% of viewport width, set sizes
to 100vw
and the browser will select the image in the srcset
that is closest to the viewport width (after accounting for pixel density). If your image is only likely to take up half the screen (ex: in a sidebar), set sizes
to 50vw
to ensure the browser selects a smaller image. And so on.
If you find that the above does not cover your desired image behavior, see the documentation on advanced sizes values.
By default, the responsive breakpoints are:
[16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]
If you would like to customize these breakpoints, you can do so using the IMAGE_CONFIG
provider:
If you would like to manually define a srcset
attribute, you can provide your own directly, or use the ngSrcset
attribute:
<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w">
If the ngSrcset
attribute is present, NgOptimizedImage
generates and sets the srcset
using the configured image loader. Do not include image file names in ngSrcset
- the directive infers this information from ngSrc
. The directive supports both width descriptors (e.g. 100w
) and density descriptors (e.g. 1x
) are supported.
<img ngSrc="hero.jpg" ngSrcset="100w, 200w, 300w" sizes="50vw">
To disable srcset generation for a single image, you can add the disableOptimizedSrcset
attribute on the image:
<img ngSrc="about.jpg" disableOptimizedSrcset>
By default, NgOptimizedImage
sets loading=lazy
for all images that are not marked priority
. You can disable this behavior for non-priority images by setting the loading
attribute. This attribute accepts values: eager
, auto
, and lazy
. See the documentation for the standard image loading
attribute for details.
<img ngSrc="cat.jpg" width="400" height="200" loading="eager">
You may want to have images displayed at varying widths on differently-sized screens. A common example of this pattern is a grid- or column-based layout that renders a single column on mobile devices, and two columns on larger devices. You can capture this behavior in the sizes
attribute, using a "media query" syntax, such as the following:
<img ngSrc="cat.jpg" width="400" height="200" sizes="(max-width: 768px) 100vw, 50vw">
The sizes
attribute in the above example says "I expect this image to be 100 percent of the screen width on devices under 768px wide. Otherwise, I expect it to be 50 percent of the screen width.
For additional information about the sizes
attribute, see web.dev or mdn.
@reviewed 2022-08-25