Next.js Image Optimization

Building modern web apps with any framework almost always involves the need for image optimization, and the NextJs image optimization is no exception. Image optimization is important for several reasons, which we’ll go over, along with how these concepts apply to Next.js specifically.

SEO Consultant

Free Weekly SEO Newsletter

Hey! I’m Scott, I’ve been an SEO consultant for nearly 10 years. Get on my weekly newsletter to get..

  • Weekly SEO updates, keep up with the latest and greatest.
  • How we grow websites from zero to millions of visitors
  • A bunch of SEO tips and Tricks you won’t find anywhere else test

TL;DR: NextJs Image Optimization & Quick Links

If your website images are huge, they will have a negative effect on search engine rankings. If you compress them, you’ll likely see a meaningful increase in organic traffic.

Why is image optimization and compression important for SEO?

Fast page speed and excellent user experience translates to great SEO metrics. It’s important to know and apply best practices to ensure your project can rank in a modern and competitive online marketplace.

Facilitating image optimization is a focal point for many frameworks. NextJs has a unique approach to this problem, offering an Image component that’s extremely convenient, effective, and easy to use.

How to Optimize Images With NextJs | The Basics

The NextJs framework comes equipped with an image component that has many great features, such as automatic image compression and responsive image loaders. The Image component converts images to the .webp file format, which we’ll talk more about later.

The Image component accepts an image file as a parameter (remote image), or an imported image object (local image). Remote images within your project must be located in the /public directory of your project.

At build time, the image will be converted and compressed accordingly, and plugged-in to a standard HTML tag for the client to consume.

Basic usage is simple, here’s an example:

import Image from 'next/image';
 
export default function ImgComponent() {
  return (
    <>
         <Image src="/example.png" height={150} width={150} alt="Sample" />
    </>

Notice that we had to set the width and height manually. That’s because this example utilizes a remote image rather than a local image (more on that later).

This simple JSX markup does a lot of work under the hood, converting and compressing your image to the .webp format while preserving image quality.

We’re going to get a little more in-depth with the Image component in a bit. However, let’s do a quick review on SEO optimization concepts as pertains to images on the web.

SEO | Image Optimization Concepts

Many concepts are universal regarding image optimization on the web, and we should go over some of the more important aspects before diving into the NextJs Image component and seeing what it can do.

Decrease the file size for faster page load speed.

Usually, the overall goal is to serve the smallest possible file size while preserving the image quality. There are multiple ways to accomplish this, from compression to responsive image loaders. Or both.

Name image files appropriately.

When creating images for your site, it’s important to give the image file a relevant name for what the image is depicting. This also goes for the image alt tag and caption; it’s important to show Google that your media is relevant to the actual content you’re offering the user.

Utilizing content delivery networks.

Content delivery networks (CDNs) are services that will cache your site’s content on servers all over the country. When someone requests your site, the nearest CDN server will respond with an up to date cache of whichever media the client requested, significantly increasing page speed. This tech doesn’t only apply to images, but it’s relevant for our purposes.

Choosing the right file format.

There are 5 main image file formats to consider when it comes to web design. Let’s take a quick look at what each brings to the table:

  • JPEG – Best for larger photos. Lossy and raster based, which means it will lose quality during compression.
  • PNG – Preserves transparent backgrounds, which comes in handy. Lossless, which means even after compression the file size will only shrink so much.
  • WebP – Optimal compression over jpeg or png by about 25%, and preserves transparency. This format is used by NextJs Image because it offers a good middle ground between quality and optimization.
  • AVIF – Same as webp but with 20% more compression. Takes 20% longer to compress on the fly, which is why NextJs opts for WebP.
  • SVG – Best for line drawings that can scale while remaining small in size, such as logos.

Although NextJs does a good job producing quality compressed images on the fly with the webp format, it’s important to be familiar with these options. 

When it comes to images, unique cases tend to present themselves when least expected, and this knowledge will help you identify when the Image component may need to be tweaked, or abandoned altogether.

NextJs Image Component | An Optimization Tool

It’s important to remember that the Image component is simply an extension of the HTML img tag. There’s no unfamiliar magic going on here, it’s just another optional optimization tool offered by the NextJs framework.

Let’s take a glance at what the Image component has to offer:

  • Image loader – Image loaders are functions that generate the URL endpoints for your images. NextJs defaults to its own loader, but allows you to use third-party loaders, or set up a custom loader. The default image loader will generate multiple images to be served at specific breakpoints depending on the device’s screen size, using the srcset property.
  • No cumulative layout shift (CLS) – Using techniques to ensure a height and width value is always set on your images, CLS is avoided. CLS is when a page layout shifts as images are loaded into the page, creating an annoying effect that’s bad for UX. This is a subtle but important SEO metric that is used by Google to rank web pages.
  • Automatic image conversion and compression – NextJs defaults to using squoosh, a tool built by the guys at GoogleChromeLabs, to convert images to the webp format. This process is completely automated and doesn’t require any extra work.
  • Lazy loading – A technique for increasing page speed by only loading an image once it’s in the viewport, i.e visible on the screen. The Image component defaults to using lazy loading.
  • Image placeholder – A feature that allows the developer to specify a placeholder image or blur that is displayed until the actual image has completed loading. Serving some content instead of nothing is preferable, even if for only a brief moment.

Now that we have a good idea of what the Image component brings to the table, let’s take a closer look at the two ways we can load image files into the component.

The src Property | Local vs Remote Images

As we saw in the first example, the src property is where we set the location of the image. In the example, we used a relative URL, which tells NextJs that our image is remote. This may seem strange because in this case, the image is actually located in our local projects /public folder. However, this definition makes perfect sense. NextJs can only have access to the file at build time if it’s imported into the component. Therefore, if the image isn’t imported, you must specify the width and height of the remote image because the Image component has no way to obtain this information without direct access.

The image exists locally, but it’s remote relative to the component.

Although using remote images is fairly common, it can be a pain configuring a viable solution that keeps the image aspect ratio without any clipping. This is why it’s usually recommended to use local images and the default NextJs image loader, which works really well for most cases anyways.

That being said, let’s take a look at what kind of results we can achieve by importing an image locally into our component.

Testing the NextJs Image Component Optimization

We’ll start with a test image, test.png, that has a transparent background and is 206kb in size. Not huge, but we can do better. So, let’s import this image into our component and check out the output:

import Image from 'next/image';
import testImg from ‘../public/test.png’;
 
export default function ImgComponent() {
  return (
    <>
         <Image src={testImg} alt="Sample" />
    </>

Note: We didn’t need to explicitly declare the width and height, because we used a local image.

After saving this component and refreshing our browser, we can download the image and view its properties.

As expected, our .png image is now in the .webp format. But the impressive metric here is the file size, coming in at a tiny 46.5kb! That’s a 72% decrease in size from our original 206kb, while maintaining the original image resolution; not bad at all.

We can achieve even more impressive results in some cases, and less in others. The resulting file size is largely dependent on a number of factors, such as color type and image detail. Behind the scenes, the Squoosh compression engine is doing great things.

How to disable image optimization for NextJs?

Disabling image optimization in your NextJs app is as simple as using a standard HTML <img /> tag. Let’s take a look at how this works, and when you may opt for this method rather than utilizing the Image component.

NextJs Image vs HTML img Tag | Which is better?

In most cases, the Image component will usually be the optimal solution over a standard HTML img tag. However, there are a few edge cases where utilizing a standard HTML could be beneficial.

Some Reasons for using HTML img Tag Over Next Image

  • For cases where the dimensions of remote images may be unknown. This is because (for remote images) the NextJs Image component requires a height and width property, or a layout property. So, if you’re unsure of the dimensions or aspect ratio, the standard img tag offers a little more flexibility with CSS styling.
  • When you’d like to use advanced effects libraries like framer-motion, you’ll need to use the standard img tag.

Using a standard HTML img tag is simple. Just plug in the `<img />` tag in place of where you would use your Next Image component. All the standard features of React JSX transpiling with Babel still apply when using Next.

Despite the above cases, using the Image component is usually preferred. It can drastically speed up development while benefiting from the inherent optimization features that can really speed up development without compromising SEO best practices.

NextJs Image Optimization | Overview and Conclusion

As we’ve seen, the NextJs Image component is a powerful tool for quickly achieving optimal Nextjs SEO performance. It can be quickly set up to drastically compress images on the fly, while preserving image properties such as background transparency, dimensions, and overall quality.

NextJs is a flexible framework, and gives developers the freedom to discard the Image component completely. If you’re comfortable with your current method of image optimization, you can simply opt for using the traditional HTML img tag, and apply styles or other optimizations as you see fit.

In our opinion, it’s worth setting aside some time to fully understand the ins and outs of this component’s features. We went over most of the basic usage in this article, but it’s always a good idea to head over to the NextJs docs and familiarize yourself with all the little details. 

Leave a Comment

oh my crawl logo
Digital Architecture
For Search Engines
Javascript Frameworks
Most Js Frameworks..
Contact
Brooklyn, NY 11219

Blog