Image Optimization and Lazy Loading
Tags: angular, tutorial
Published: 2024-06-17 13:03:18

In the era of modern frontends, we often raise the question, "How do I make my application more performant?" In this article, I will discuss image optimization and lazy loading to help improve performance and make our application increasingly faster.

**_Images are always a problem in the life of frontenders._**

Very large and heavy images can hinder our application in various aspects, from super slow loading when you have a not-so-fast internet connection, especially when on 3G or 4G, to the initial bootstrap on a desktop, failing to provide elegant feedback to the user. There are many other issues we encounter along the way as well, hehe.

Here, I present some good practice ideas to assist in application development and perhaps provide some tips for those facing this issue. We will use the `NgOptimizedImage` directive, which helps improve image loading speed.

We will create the project using the Angular CLI. I will assume you already know what we are talking about and import the `NgOptimizedImage` directive in the AppModule file. **Remember that this directive is available from version 14.2.0 onwards.**

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

@NgModule({
  imports: [
    NgOptimizedImage
  ]
})
export class AppModule { }

// If you are using standalone, it can be done as below.

@Component({
  standalone: true,
  imports: [NgOptimizedImage],
})
class StandaloneComponent {}
```

Change the `src` property to `ngSrc` in your HTML template and it will also be necessary to set a width and height.

```html
<img
  ngSrc="../assets/img/image.jpeg"
  width="4000"
  height="3000"
/>
```

For responsive images, provide various sizes so the browser can choose the best one to render, thus avoiding performance loss.

```html
<img
  ngSrc="../assets/img/image.jpeg"
  width="4000"
  height="3000"
  ngSrcset="200w, 400w, 600w, 800w, 1000w, 1200w, 1600w, 2000w, 3000w"
/>
```

The Angular `NgOptimizedImage` directive already loads images by default with lazy loading, but non-visible images should also be loaded this way.

For example, images in a carousel or those lower down the page do not need to be "loaded" when the page is first called. For this, we use another attribute to assist, which is `priority`.

```html
<img
  ngSrc="../assets/img/image.jpeg"
  width="4000"
  height="3000"
  ngSrcset="200w, 400w, 600w, 800w, 1000w, 1200w, 1600w, 2000w, 3000w"
  priority
/>
```

With this, all images shown on the page to the user will be marked with priority and will load first. If you have a CDN, from this version of Angular onwards, you can add the provider `provideImageKitLoader`, making it easier to import images.

```ts
import { NgOptimizedImage, provideImageKitLoader } from '@angular/common';

@NgModule({
  imports: [
    NgOptimizedImage
  ],
  providers: [
    provideImageKitLoader("cdn_url")
  ],
})
export class AppModule { }
```

By doing this, you only need to use the image name in the `src`, without always typing the full image path, as it will already be called in the provider.

```html
<img
  ngSrc="image.jpeg"
  width="4000"
  height="3000"
  ngSrcset="200w, 400w, 600w, 800w, 1000w, 1200w, 1600w, 2000w, 3000w"
  priority
/>
```

Below are some data showing the differences between using lazy loading and not.

Without Lazy Loading
![Without Lazy Loading](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/js5k9rl14u7d7sa631z5.png)

With Lazy Loading
![With Lazy Loading](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hqqxfj27dcnmm3etk4e7.png)

These were some tips on how we can use image lazy loading to our advantage, bringing faster loading speeds to our pages and providing good usability for the user.

twitter @joaopaulo_avila