> ## Content Index
> Fetch the complete content index at: https://www.angularspace.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Boost Your App's Performance with NgOptimizedImage
- URL: https://www.angularspace.com/boost-your-apps-performance-with-ngoptimizedimage/
- Published: 2025-01-22T10:28:24.000Z
- Updated: 2025-01-22T10:28:54.000Z
- Author: Jaroslaw Zolnowski
- Tags: performance, angular 14, imageoptimization, lcp, Articles

If you've worked on a web app, you know images can be a big deal for design and performance. While they make pages look great, they can also slow everything down. That’s where Angular’s `NgOptimizedImage` directive comes in. It’s a handy tool for optimizing images, so they load faster without losing quality. Let’s dive into how this directive can make your Angular app snappier and improve the user experience.

---

## Why Optimize Images Anyway?

We all want our apps to look good, but images come with a cost - longer load times. Optimizing images can dramatically improve performance metrics, especially the [Largest Contentful Paint (LCP)](https://developer.chrome.com/docs/lighthouse/performance/lighthouse-largest-contentful-paint?ref=angularspace.com), which measures how fast the largest piece of content appears on the screen. This is huge for user experience and SEO, and Angular’s `NgOptimizedImage` directive makes it easy to get it right without manual tweaks.

---

## Getting Started

The first step is to import the `NgOptimizedImage` directive from the `@angular/common` module. You can do this in your standalone component or module file:

```typescript
import { NgOptimizedImage } from '@angular/common';

@Component({
  // ...
  imports: [
    NgOptimizedImage,
    // ... other imports
  ],
  // ...
})
export class DemoComponent {}

```

Once imported, you can use the key image optimization features provided by `NgOptimizedImage`.

## Key Features of `NgOptimizedImage`

### 1\. Responsive Images with `srcSet` and `sizes`

The `srcSet` and `sizes` attributes allow the browser to load the right image size for each device, which is especially helpful for performance. The great thing about Angular’s `NgOptimizedImage` directive is that it generates the `srcSet` for you, so you don’t need to do it manually.

**Example:**

```html
<img
  ngSrc="angular.jpg"
  width="200"
  height="200"
  sizes="80vw"
/>

```

Here, `sizes="80vw"` sets the image to 80% of the viewport width. Angular will handle the rest, creating a `srcSet` with various resolutions so that each device gets the best fit. This saves time and ensures a smooth load no matter the screen size.

### 2\. Customizing Image Breakpoints

If you’re working with specific screen sizes, Angular lets you customize breakpoints by setting an `IMAGE_CONFIG` token. This way, you can pick just the breakpoints that match your app’s design.

**Example:**

```typescript
providers: [{
  provide: IMAGE_CONFIG,
  useValue: {
    breakpoints: [384, 640, 750]
  }
}]

```

Now Angular will only generate images for 384px, 640px, and 750px, which keeps your file sizes smaller and your app faster.

---

### 3\. Prioritizing Key Images with `priority`

Ever noticed how long it can take to load a big image like a banner? The `priority` attribute tells Angular which images are critical for loading first. If you set `priority`, Angular preloads the image, making sure it appears quickly, improving that all-important LCP. On top of that, it assigns the image a `fetchpriority=high`, signaling its importance, and sets the loading behavior to `eager` to make sure there's no unnecessary delay in displaying it

**Example:**

```html
<img
  ngSrc="hero.jpg"
  width="1200"
  height="600"
  priority
/>

```

For server-side rendered apps, Angular even adds a `<link rel="preload">` tag for these images, so they start loading right away. This is perfect for hero images or banners that you want users to see immediately.

---

### 4\. Fill Mode for Flexible Layouts

Need an image to fill a container, like a background? `fill` mode has you covered. It lets an image scale to fit the container without needing fixed dimensions, which is perfect for layouts with unknown widths or heights.

**Example:**

```html
<img ngSrc="background.jpg" fill/>

```

Just make sure your container has `position: relative`, `absolute`, or `fixed`, so the image fills it properly. This feature is great for responsive layouts where you want images to adapt smoothly.

---

### 5\. Lazy Loading for Off-Screen Images

Angular makes lazy loading effortless with `loading="lazy"`, which defers loading images until they’re about to be visible. This reduces the initial page load and is awesome for things like image galleries.

**Example:**

```html
<img
  ngSrc="thumbnail.jpg"
  width="200"
  height="200"
  loading="lazy"
/>

```

Be cautious with images that are crucial to the layout. Avoid using lazy loading for LCP images, such as a logo. This ensures they load immediately and maintain a smooth user experience.

---

### 6\. Placeholders for a Better Loading Experience

Nothing kills user experience like a blank loading image. With `placeholder`, you can show a temporary low-res version or even a Base64-encoded preview while the main image loads. This provides a smoother experience as users see a preview  
of the image right away.

**Example:**

```html
<img
  ngSrc="profile.jpg"
  width="200"
  height="200"
  placeholder
/>

```

If you'd like to use a Base64-encoded placeholder, you can easily generate the string using:

- Online Tools: Use a free online Base64 converter like [Base64-Image](https://www.base64-image.de/?ref=angularspace.com), and  
it will generate the encoded string.
- Command Line Tools: Open a terminal and type the following command:  
```bash  
base64 -i input-image.jpg  
```

Once you have the Base64 string, you can embed it directly into your HTML as the src for the placeholder:

```html
<img
  ngSrc="profile.jpg"
  width="200"
  height="200"
  placeholder="data:image/jpeg;base64,/9j/4AAQSk..."
/>

```

This approach makes the user experience smoother and creates a seamless visual flow.

If you use a CDN, you can [generate low-res placeholders](https://cloudinary.com/blog/guest%5Fpost/create-image-loading-placeholders-in-nuxtjs?ref=angularspace.com) automatically. Just keep them small (under 4 KB) to avoid slowing down the load. Angular will even throw an error if the placeholder size is too big, which is a good reminder to keep things light:

```
NG02965: The NgOptimizedImage directive (activated on an <img> element with the ngSrc="angular.jpg") has detected that the placeholder attribute is set to a data URL which is longer than 4000 characters. This is discouraged, as large inline placeholders directly increase the bundle size of Angular and hurt page
load performance. For better loading performance, generate a smaller data URL placeholder.

```

---

## CDN Integration for Faster Image Delivery

By using a Content Delivery Network (CDN) with `NgOptimizedImage`, you get faster load times because images are served from servers closer to your users. CDNs cache content across the globe, meaning shorter load times and less data travel, which makes a huge difference, especially for users far from your primary server.

CDNs also often compress images, ensuring the best quality at the smallest size, which boosts performance even further. When combined with `NgOptimizedImage`, CDNs can help you build a fast, responsive app that works well for users  
everywhere.

---

## A Practical Example

Now, let's look at a real-world example to see how the `NgOptimizedImage` directive can make a big difference in performance. Imagine we’re building a gaming site that displays game cover images.

![](https://storage.ghost.io/c/3f/63/3f6333b8-1f83-4017-8426-91bfbc264d81/content/images/2025/01/demo-app-1.png)

Here’s the initial setup with the standard `src` attribute:

```html
<img
  width="1250"
  height="600"
  src="https://via.assets.so/game.png?id=12"
  alt="Assassin's Creed Game Cover Art"
/>

<div style="...">
  @for (image of list; track $index) {
    <img
      src="https://via.assets.so/game.png?id=16"
      width="400"
      height="200"
      alt="Thumbnails Game Gallery"
    />
  }
</div>

```

When we analyze the page in Lighthouse, the First Contentful Paint (FCP) comes in at 1.4 seconds, while the Largest Contentful Paint (LCP) lags behind at 13.5 seconds, which is not ideal.

![](https://storage.ghost.io/c/3f/63/3f6333b8-1f83-4017-8426-91bfbc264d81/content/images/2025/01/demo-app-initial-lighthouse-score-3.png)

By making a few tweaks with `NgOptimizedImage`, we can get those numbers way down:

```html
<img
  width="1250"
  height="600"
  src="game.png?id=12"
  ngSrcset="400w, 800w, 1250w"
  sizes="(max-width: 600px) 960px, 100vw"
  alt="Assassin's Creed Game Cover Art"
  priority
/>

<div style="...">
  @for (image of list; track $index) {
    <img
      width="400"
      height="200"
      [ngSrc]="game.png?id=16"
      ngSrcset="100w, 200w, 400w"
      sizes="(max-width: 600px) 200px, 400px"
      alt="Thumbnails Game Gallery"
      priority
    />
  }
</div>

```

> \*\* **Important Note:** Setting the priority for multiple images displayed in a loop isn’t always the best approach, specially when some of them aren’t immediately visible in the viewport. To optimize performance, it’s better to assign fetchpriority="high" only to the visible images, while using loading="lazy" for those outside the viewport. This ensures efficient loading and better resource management.

To go the extra mile, we add a `preconnect` link for our image server in the `<head>`:

```html

<link rel="preconnect" href="https://via.assets.so/">

```

And in our app configuration, we set up a [custom image loader](https://angular.dev/guide/image-optimization?ref=angularspace.com#configuring-an-image-loader-for-ngoptimizedimage) for our CDN (e.g., `Imgix`):

```typescript
const appConfig: ApplicationConfig = {
  providers: [provideImgixLoader('https://via.assets.so/')],
};

```

With these small adjustments, we see a huge performance boost—FCP drops to just 0.2 seconds, and LCP is down to a quick 0.7 seconds! This is a perfect example of how `NgOptimizedImage` can make a real difference in your app’s speed and user experience.

![](https://storage.ghost.io/c/3f/63/3f6333b8-1f83-4017-8426-91bfbc264d81/content/images/2025/01/demo-app-final-lighthouse-score.png)

---

## Wrapping Up

Angular’s `NgOptimizedImage` is a fantastic tool for improving image handling and app performance. Whether you’re working with responsive images, lazy loading, or CDN integration, this directive makes it easy to get things right. With these optimizations, you’ll have a faster, smoother app that keeps users happy. Give `NgOptimizedImage` a try and see the difference in your next project!

---

![](https://storage.ghost.io/c/3f/63/3f6333b8-1f83-4017-8426-91bfbc264d81/content/images/2025/01/Screenshot-2024-11-13-at-15.52.00--1---3-.jpg)