docs: add image directive guide (#47155)

PR Close #47155
This commit is contained in:
Katie Hempenius
2022-08-23 20:00:58 +00:00
committed by Alex Rickabaugh
parent 9e02af8c7c
commit 40d8821dde
4 changed files with 208 additions and 1 deletions
@@ -0,0 +1,96 @@
# Setting up `NgOptimizedImage`
This tutorial explains how to setup the `NgOptimizedImage`. For information on using `NgOptimizedImage`, see [Getting Started with NgOptimizedImage](/guide/image-directive).
## Import `NgOptimizedImage`
You can import `NgOptimizedImage` from the `@angular/common` module. The directive is defined as a [standalone directive](/guide/standalone-components), so components should import it directly.
## Configure an `ImageLoader`
A "loader" is a function that generates the [image transformation URL](https://web.dev/image-cdns/#how-image-cdns-use-urls-to-indicate-optimization-options) for a given image file. When appropriate, `NgOptimzedImage` sets the size, format, and image quality transformations for an image.
`NgOptimizedImage` provides a generic loader as well as loaders for various third-party image services; it also supports writing your own custom loader.
| Loader type| Behavior |
|:--- |:--- |
| Generic loader | The URL returned by the generic loader will always match the value of `src`. In other words, this loader applies no transformations. Sites that use Angular to serve images are the primary intended use case for this loader.|
| Loaders for third-party image services | The URL returned by the loaders for third-party image services will follow API conventions used by that particular image service. |
| Custom loaders | A custom loader's behavior is defined by its developer. You should use a custom loader if your image service isn't supported by the loaders that come preconfigured with `NgOptimzedImage`.|
Based on the image services commonly used with Angular applications, `NgOptimizedImage` provides loaders preconfigured to work with the following image services:
| Image Service | Angular API | Documentation |
|:--- |:--- |:--- |
| Cloudflare Image Resizing | `provideCloudflareLoader` | [Documentation](https://developers.cloudflare.com/images/image-resizing/) |
| Cloudinary | `provideCloudinaryLoader` | [Documentation](https://developers.cloudflare.com/images/image-resizing/) | |
| ImageKit | `provideImageKitLoader` | [Documentation](https://docs.imagekit.io/) |
| Imgix | `provideImgixLoader` | [Documentation](https://docs.imgix.com/) |
You must configure an image loader to use `NgOptimizedImage`.
These instructions explain how to setup an image loader for use with the `NgOptimizedImage`.
1. Import the `NgOptimizedImage` directive into the application by adding it to the `imports` section of an NgModule or a standalone Component.
<code-example format="typescript" language="typescript">
import { NgOptimizedImage } from '@angular/common';
// Include NgOptimizedImage in the appropriate NgModule
@NgModule({
imports: [
// ... other imports
NgOptimizedImage,
],
})
class AppModule {}
</code-example>
<code-example format="typescript" language="typescript">
@Component({
standalone: true,
imports: [
// ... other imports
NgOptimizedImage,
],
})
class MyStandaloneComponent {}
</code-example>
2. Configure a loader that you want to use.
To use the **generic loader**: no additional code changes are necessary.
To use an existing loader for a **third-party image service**: add the provider factory for your chosen service to the `providers` array. In the example below, the Imgix loader is used:
<code-example format="typescript" language="typescript">
providers: [
provideImgixLoader('https://my.base.url/'),
],
</code-example>
The base URL for your image assets should be passed to the provider factory as an argument. For most sites, this base URL should match one of the following patterns:
* https://yoursite.yourcdn.com
* https://subdomain.yoursite.com
* https://subdomain.yourcdn.com/yoursite
You can learn more about the base URL structure in the docs of a corresponding CDN provider.
To use a **custom loader**: provide your loader function as a value for the `IMAGE_LOADER` DI token. In the example below, the custom loader function returns a URL starting with `https://example.com` that includes `src` and `width` as URL parameters.
<code-example format="typescript" language="typescript">
providers: [
{
provide: IMAGE_LOADER,
useValue: (config: ImageLoaderConfig) => {
return `https://example.com/images?src=${config.src}&width=${config.width}`;
},
},
],
</code-example>
A loader function for the `NgOptimizedImage` directive takes an object with the `ImageLoaderConfig` type (from `@angular/common`) as its argument and returns the absolute URL of the image asset. The `ImageLoaderConfig` object contains the `src`and `width` properties.
Note: a custom loader must support requesting images at various widths in order for `rawSrcset` to work properly.
+99
View File
@@ -0,0 +1,99 @@
# Getting started with NgOptimizedImage
Note: the `NgOptimizedImage` directive is currently in the [“Developer Preview” mode](https://angular.io/guide/releases#developer-preview). The Angular team will stabilize the APIs based on the feedback and will make an announcement once the APIs are fully 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](http://web.dev/lcp) 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](https://web.dev/image-cdns/#how-image-cdns-use-urls-to-indicate-optimization-options)
* Requires that `width` and `height` are set
* Warns if `width` or `height` have been set incorrectly
* Warns if the image will be visually distorted when rendered
## Prerequisites
You will need to import the directive into your application. In addition, you will need to setup an image loader. These steps are explained in the [Setting up `NgOptimizedImage`](/guide/image-directive-setup) tutorial.
## Usage in a template
### Overview
To activate the `NgOptimizedImage` directive, replace your image's `src` attribute with `rawSrc`.
<code-example format="typescript" language="typescript">
<img rawSrc=”cat.jpg" width="400" height="200">
</code-example>
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](https://web.dev/css-web-vitals/#images-and-layout-shifts). The `width` and `height` attributes should reflect the [intrinsic size](https://developer.mozilla.org/en-US/docs/Glossary/Intrinsic_Size) of the image. During development, the `NgOptimizedImage` warns if it detects that the `width` and `height` attributes have been set incorrectly.
### Marking images as `priority`
Always mark the [LCP image](https://web.dev/lcp/#what-elements-are-considered) on your page as `priority` to prioritize its loading.
<code-example format="typescript" language="typescript">
<img rawSrc="cat.jpg" width="400" height="200" priority>
</code-example>
Marking an image as `priority` applies the following optimizations:
* Sets `fetchpriority=high` (read more about priority hints [here](https://web.dev/priority-hints/))
* Sets `loading=eager` (read more about native lazy loading [here](https://web.dev/browser-level-image-lazy-loading/))
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](https://web.dev/css-web-vitals/#images-and-largest-contentful-paint-lcp) for more details.
### Adding resource hints
You can add a [`preconnect` resource hint](https://web.dev/preconnect-and-dns-prefetch/) 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.
<code-example format="html" language="html">
<link rel="preconnect" href="https://my.cdn.origin" />
</code-example>
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:
<code-example format="typescript" language="typescript">
providers: [
provideImgixLoader('https://my.base.url', {ensurePreconnect: false})
],
</code-example>
### Adjusting image styling
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](https://web.dev/patterns/web-vitals-patterns/images/img-tag/).
### Handling `srcset` attributes
If your `<img>` tag defines a `srcset` attribute, replace it with `rawSrcset`.
<code-example format="html" language="html">
<img rawSrc="hero.jpg" rawSrcset="100w, 200w, 300w">
</code-example>
If the `rawSrcset` attribute is present, `NgOptimizedImage` generates and sets the [`srcset` attribute](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset) using the configured image loader. Do not include image file names in `rawSrcset` - the directive infers this information from `rawSrc`. The directive supports both width descriptors (e.g. `100w`) and density descriptors (e.g. `1x`) are supported.
You can also use `rawSrcset` with the standard image [`sizes` attribute](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/sizes).
<code-example format="html" language="html">
<img rawSrc="hero.jpg" rawSrcset="100w, 200w, 300w" sizes=”50vw”>
</code-example>
### Disabling image lazy loading
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](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/loading#value).
<code-example format="html" language="html">
<img rawSrc="cat.jpg" width="400" height="200" loading="eager">
</code-example>
+11 -1
View File
@@ -637,6 +637,11 @@
"url": "guide/prerendering",
"title": "Prerendering",
"tooltip": "Prerender HTML server-side with Angular Universal."
},
{
"url": "guide/image-directive",
"title": "Image Directive",
"tooltip": "Performant images with the Angular image directive."
}
]
},
@@ -816,7 +821,12 @@
"tooltip": "Create a template-driven form using directives and Angular template syntax."
},
{
"title": "Angular libraries",
"url": "guide/image-directive-setup",
"title": "Setting up NgOptimzedImage",
"tooltip": "Setup the Angular image directive"
},
{
"title": "Angular Libraries",
"tooltip": "Extending Angular with shared libraries.",
"children": [
{