This content originally appeared on Telerik Blogs and was authored by Hassan Djirdeh
Learn how the NgOptimizedImage directive can be used to optimize images in an Angular app by allowing developers to easily leverage features like lazy loading, image placeholders and automatic resizing.
Angular provides a broad suite of tools, APIs and libraries for building dynamic and responsive user interfaces. In a previous article, we’ve seen how Angular’s control flow blocks (@if
, @for
and @switch
) allow us to easily manipulate the DOM, bind data and control the flow of our application’s user interface.
In today’s article, we’ll explore how the NgOptimizedImage directive can be used to optimize images in an Angular app.
NgOptimizedImage
An important aspect of creating a seamless user experience in web applications is optimizing images to ensure they load efficiently and effectively. NgOptimizedImage is a built-in Angular directive that can be used to simplify image optimization as it allows us to easily optimize images by compressing, resizing and caching them. This results in faster page loads, reduced bandwidth consumption and improved overall performance.
To use the NgOptimizedImage
directive, we can first import it from the @angular/common
directory:
import { NgOptimizedImage } from "@angular/common";
When imported, we can add the directive into the imports
array of a certain Angular component or module.
import { NgOptimizedImage } from "@angular/common";
@Component({
imports: [NgOptimizedImage],
})
export class ImageComponent {}
Once the NgOptimizedImage
directive is included in the imports of your component or module, we can utilize the ngSrc
attribute in your image elements to activate image optimization.
import { NgOptimizedImage } from "@angular/common";
@Component({
template: `<img ngSrc="https://www.telerik.comdog.png" alt="Descriptive alt text" />`,
imports: [NgOptimizedImage],
})
export class ImageComponent {}
ngSrc
replaces the standard src
attribute, signaling Angular to handle the image using the optimizations provided by the NgOptimizedImage
directive.
Priority
The NgOptimizedImage
directive provides various configuration options to customize image optimization. As an example, for images critical to layout, such as Largest Contentful Paint (LCP) elements, the Angular documentation recommends always marking them with the priority
attribute:
import { NgOptimizedImage } from "@angular/common";
@Component({
template: `
<img
priority
ngSrc="https://www.telerik.comdog.png"
alt="Descriptive alt text"
/>
`,
imports: [NgOptimizedImage],
})
export class ImageComponent {}
Marking an image with the priority
tag prioritizes the image’s loading by using fetchpriority="high"
and loading="eager"
. This not only prioritizes the image’s loading but also ensures the preloading of the image, which means it instructs the browser to download the image as soon as possible, even before processing the rest of the page content. This is particularly useful for images that are critical to maintaining a good user experience by reducing visual load times and improving perceived performance.
Width and Height
Setting the width and height of images helps maintain the layout stability of a webpage as these images load. Without these attributes, page content might shift unexpectedly as images load, which can negatively impact the user experience and cause layout shifts, often measured as Cumulative Layout Shift (CLS) in performance metrics.
In order to prevent unexpected layout shifts, the NgOptimizedImage
directive requires us to specify the width
and height
attributes directly on our image element.
import { NgOptimizedImage } from "@angular/common";
@Component({
template: `
<img
width="600"
height="400"
ngSrc="https://www.telerik.comdog.png"
alt="Descriptive alt text"
/>
`,
imports: [NgOptimizedImage],
})
export class ImageComponent {}
Fill
The fill
attribute can be used to adjust how images fit within their designated space in a responsive and visually appealing manner. This attribute is useful when dealing with images in a fluid or responsive layout where the size of the image container might change depending on the viewport or device (i.e., we want the image to “fill” a containing space).
import { NgOptimizedImage } from "@angular/common";
@Component({
template: `
<img
fill
ngSrc="https://www.telerik.comdog.png"
alt="Descriptive alt text"
/>
`,
imports: [NgOptimizedImage],
})
export class ImageComponent {}
When using the fill
property, we should not specify explicit height
or width
attributes on the image element, as the intention is to allow the image to dynamically adapt to the size of its container, filling the space as needed based on the layout constraints.
Placeholders
The placeholder
attribute is another useful feature that can be employed alongside the NgOptimizedImage
directive to enhance image handling in Angular applications. This attribute helps to manage how images are displayed while they are loading, providing a better user experience by avoiding blank spaces or abrupt jumps in the layout.
Automatic Placeholders
If our setup includes a content delivery network (CDN) or an image hosting service that supports automatic resizing, the NgOptimizedImage
directive allows us to utilize automatic placeholders. These are typically low-resolution versions of the original images that load quickly, providing a preview while the full-resolution image loads and can be applied by simply adding the placeholder
attribute:
import { NgOptimizedImage } from "@angular/common";
@Component({
template: `
<img
placeholder
ngSrc="https://www.telerik.comdog.png"
width="600"
height="400"
/>
`,
imports: [NgOptimizedImage],
})
export class ImageComponent {}
Data URL Placeholders
For situations where an image loader is unavailable or unsuitable, a data URL can serve as a placeholder. This involves encoding a small version of the image directly in Base64 format:
import { NgOptimizedImage } from "@angular/common";
@Component({
template: `
<img
placeholder="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAADSCA..."
ngSrc="https://www.telerik.comdog.png"
width="600"
height="400"
/>
`,
imports: [NgOptimizedImage],
})
export class ImageComponent {}
While this method can increase the initial load size of your HTML, it’s effective for critical images where you must ensure immediate availability without relying on external resources.
Non-blurred Placeholders
For scenarios where a more distinct, clear placeholder is preferred over the default blurred version, the NgOptimizedImage
directive can be configured to use non-blurred placeholders. This option is particularly useful when maintaining a certain aesthetic or when the blurred effect may detract from the user interface design:
import { NgOptimizedImage } from "@angular/common";
@Component({
template: `
<img
placeholder
[placeholderConfig]="{ blur: false }"
ngSrc="https://www.telerik.comdog.png"
width="600"
height="400"
/>
`,
imports: [NgOptimizedImage],
})
export class ImageComponent {}
In this example, the [placeholderConfig]="{ blur: false }"
configuration explicitly disables the blur effect on the placeholder. As a result, the placeholder image will retain its original clarity but might be displayed in lower resolution or simplified detail until the full-resolution image loads.
Loaders
An image loader is a function that generates an image transformation URL for a given image file. This can be helpful in optimizing how images are served while taking into account the specific conditions and requirements of each user’s device.
The NgOptimizedImage
directive provides various loaders to support different image services and allows us to create custom loaders. There are three types of loaders that exist with NgOptimizedImage
:
- Generic Loader: Applies no transformations, returning the original image URL.
- Third-Party Image Service Loaders: Preconfigured loaders for services like Cloudflare, Cloudinary, ImageKit, Imgix and Netlify.
- Custom Loaders: Developer-defined loaders for unsupported image services or custom transformations.
To use a built-in loader (i.e., a third-party loader), we can add the provider factory to the providers
array, passing the base URL for image assets as an argument. For example:
import { NgOptimizedImage, provideCloudinaryLoader } from '@angular/common'
@Component({
template: `
<img
ngSrc="https://www.telerik.comdog.png"
width="600"
height="400"
/>
`,
imports: [NgOptimizedImage],
providers: [provideCloudinaryLoader('https://res.cloudinary.com')]
})
To use a custom loader, we can provide a loader function as a value for the IMAGE_LOADER
dependency injection token. The loader function takes an ImageLoaderConfig
object as an argument and returns the absolute URL of the image asset. For example:
import { NgOptimizedImage, IMAGE_LOADER } from '@angular/common'
@Component({
template: `
<img
ngSrc="https://www.telerik.comdog.png"
width="600"
height="400"
/>
`,
imports: [NgOptimizedImage],
providers: [
{
provide: IMAGE_LOADER,
useValue: (config: ImageLoaderConfig) => {
return `https://example.com/images?src=${config.src}&width=${config.width}`;
},
},
]
})
Wrap-up
In this article, we explored how the NgOptimizedImage
directive can be used to optimize images in an Angular app. By leveraging features like lazy loading, image placeholders and automatic resizing, developers can ensure that their apps are both efficient and visually appealing.
For more details on Angular’s image optimization capabilities, be sure to check out the official documentation on getting started with NgOptimizedImage!
This content originally appeared on Telerik Blogs and was authored by Hassan Djirdeh
Hassan Djirdeh | Sciencx (2024-06-17T08:21:52+00:00) Angular Basics: Optimizing Images with the NgOptimizedImage Directive. Retrieved from https://www.scien.cx/2024/06/17/angular-basics-optimizing-images-with-the-ngoptimizedimage-directive/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.