<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 https://www.facebook.com/tr?id=1063935717132479&amp;ev=PageView&amp;noscript=1 "> Bitovi Blog - UX and UI design, JavaScript and Frontend development
Loading

Angular |

Improve App Performance with the NgOptimizedImage Directive

Angular v14.2 includes exciting new features and improvements. In this post, learn how to implement NgOptimizedImage directive to improve app performance.

Fábio Englert Moutinho

Fábio Englert Moutinho

Twitter Reddit

In This Series: What's New in Angular v14.2

  1. Improve App Performance with the NgOptimizedImage Directive
  2. How to Use Ng Serve with Service Worker Support
  3. Developer Preview of Standalone Support in Angular Elements

Newly released Angular 14.2 comes with a nifty image optimization feature that can be used to improve the performance of your application.

In this blog post, we will take a look at the exciting new NgOptimizedImage directive and explain how we used it to make this example e-commerce application perform up to 50% better on Lighthouse scores!

image showing improved lighthouse score of Angular e-commerce app after implementing NgOptimizedImage

What is NgOptimizedImage?

NgOptimizedImage is a Directive focused on improving Image Loading performance. As a happy side-effect, NgOptimizedImage enforces best practices and improves Core Web Vitals scores, which might help your application rank higher on search engines.

Important Note: NgOptimizedImage is on Developer Preview. Features on Developer Preview might change APIs without notice. If you decide to use NgOptimizedImage on production, be aware when updating your application.

How to Use NgOptimizedImage

In order to use the NgOptimizedImage directive, identifiable by the selector img[rawSrc], you need to import NgOptimizedImage into your Module or Standalone Component.

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

Set Up an Image Loader

Image Loaders are tools that host images and provide optimization services such as image resizing or compression.

Angular now provides popular Image Loader configurations out of the box. In our e-commerce application example, we set up ImageKit with the provideImageKitLoader function, whose path argument is the default URL endpoint for an account.

// src/app/app.module.ts

// ... other imports
import { NgOptimizedImage, provideImageKitLoader } from '@angular/common';

@NgModule({
  declarations: [AppComponent, HomeComponent, CartComponent],
  imports: [BrowserModule, AppRoutingModule, ScullyLibModule, NgOptimizedImage],
  providers: [provideImageKitLoader('https://ik.imagekit.io/fabioemoutinho')],
  bootstrap: [AppComponent],
})
export class AppModule {}

Understand NgOptimizedImage Properties

NgOptimizedImage adds additional properties to an img tag:

  • rawSrc: string: instead of src full URL, rawSrc represents the source image name

  • rawSrcset: string: a comma-separated list of width or pixel density descriptors. Not required, but recommended. Usually used in conjunction with sizes attribute if you want to provide different image sources for different viewport sizes.

    <!-- example taken from https://angular.io/api/common/NgOptimizedImage#properties -->
    
    <img rawSrc="hello.jpg" rawSrcset="100w, 200w" />
    
    <!-- img tag above would output an img tag similar to the img below -->
    <img src="path/hello.jpg" srcset="path/hello.jpg?w=100 100w, path/hello.jpg?w=200 200w" />
  • priority: boolean: defaults to false; If true, adds multiple optimizations to the image

Images are going to be lazy-loaded by default. That is, it is going to be up to the browser to decide when to load the images. While lazy-loading an image is usually a good approach, in some cases, like when you want to make sure the browser will download critical images first, you might want to set the priority property to true in order to increase the performance of your app.

The NgOptimizedImage directive also expects every image to have explicit height and width attributes.

Here are the changes we had to make on a component’s template to use the NgOptimizedImage directive.

  <!-- src/app/home/home.component.html ‐‐>

  <picture class="picture block relative overflow-hidden">
    <img
-     [src]="product.image"
+     [rawSrc]="product.id + '.jpg'"
      [alt]="product.title"
      class="img not-loaded object-contain w-full h-full absolute top-0 left-0"
      (load)="onLoadImage($event)"
      (error)="onErrorImage($event)"
+     width="200"
+     height="200"
    />
  </picture>

Performance Results

In our example application, we removed scully to better measure the impact of a vanilla implementation of the NgOptimizedImage directive on the application’s home page. We tested two different scenarios:

  1. https://e-commerce-no-scully-example-angular-13.vercel.app/ - Angular 13.3.11
  2. https://e-commerce-no-scully-example.vercel.app/ - Angular 14.2.0, using NgOptimizedImage

We then ran Lighthouse locally (desktop) and had the following results:

Metric

Angular 13.3.11

Angular 14.2 with NgOptimizedImage

Impact

First Contentful Paint

0.4 s

0.3 s

25% decrease

Speed Index

1.2 s

0.6 s

50% decrease

Largest Contentful Paint

1.7 s

1.0 s

41% decrease

Time to Interactive

0.5 s

0.4 s

20% decrease

Total Blocking Time

0 ms

0 ms

-

Cumulative Layout Shift

0.003

0.003

-

Performance

93

99

6.45% increase

Even though you get excellent performance results with the automatic lazy loading of images, NgOptimizedImage shines even brighter when combining the usage of image loaders with the rawSrcset property and sizes attribute. Implementing the rawSrcset property and sizes attribute enables you to further optimize your application for different devices, especially for mobile devices.

What’s Next for Angular’s Image Directive?

Chrome’s blog post announcement about NgOptimizedImage directive presents an interesting roadmap, and we can expect many improvements like automatic srcset and sizes attributes for responsive images, automatic height and width attributes and more.

Angular v14.2 introduces other interesting features that we will talk about next, stay tuned on Bitovi's Twitter.

Need help staying up to date with the latest version of Angular to take advantage of these cool new features? Contact us for Angular Consulting help!