Exploring The New Image Component With Next.js
Next.js released an optimised image component that optimizes how images load on Next.js websites. In their own words:
"Images are always rendered in such a way as to avoid prevent Cumulative Layout Shift, a Core Web Vital that Google is going to use in search ranking." - Next.js image docs
In this post, we're going to explore and play around with this new component to see it in action.
We will use
create-next-app build out the project:
Selecting an image
For this particularly exploration, I went to Unsplash and chose an image to my taste.
In this case, I went with Florian Olivo's Jellyfish image.
Afterwards, I went to the online tool Squoosh to resize the image at 800x1199 and optimized it with the basic settings.
This created an optimized version of the image at 78KB, while the original, unoptimized version was 4.5MB.
Updating the homepage to put in both version
Following on from the example I saw in the Next.js examples repo, I altered it to show both the optimized and unoptimized image:
Essentially, that was all I need for playing around with it!
I deployed this example to Vercel to see what the results may be.
Exploring the results
When first visiting the production website, I noticed that while the images were loading, there was a nice space kept there for where the image was due to load into:
This space relates to preventing the cumulative layout shift which, as mentioned prior, is a core web vital.
During this first load, the unoptimized image took ~17 seconds to load into the page. This is due to Next.js optimizing the image before loading.
I made the rookie error of not have the
Network tab open during the first load of the project, so the timing itself is not perfect but here the Network tab of a re-deployment of the project I did later to show a similar experience to my first load:
Network tab first load
Note: You can see that the image here is optimized down from the 4.5MB of the original JPEG and it comes as
webp format, but that optimized size is far larger than the examples shown later. I cannot speak to why this happened upon re-deploying the project, but given that the image is optimized for the device and browser, I would say it may be due to re-deploying and visiting the project on my MacBook with higher resolution than my monitor.
Once loaded, we get a screen that looks like the following:
According to the docs, the caching works as so:
"Images are optimized dynamically upon request and stored in the
<distDir>/cache/images directory. The optimized image file will be served for subsequent requests until the expiration is reached. When a request is made that matches a cached but expired file, the cached file is deleted before generating a new optimized image and caching the new file.
"The expiration (or rather Max Age) is defined by the upstream server's Cache-Control header.
"If s-maxage is found in Cache-Control, it is used. If no s-maxage is found, then max-age is used. If no max-age is found, then 60 seconds is used."
So in our case, once the image has been optimized during a call, it is cached and subsequent requests will load our required image wickedly fast! Here was the network for my original deployment on reload:
Network on reloads
Today's post was about seeing Next.js image optimization in action using an unoptimized and optimized source image on a live deployment.
While this is only a surface-deep look, it is incredible to see what you get out of the box with Next.js 10 image optimization and it is certainly a great step in the right direction for helping developers.
I've been keen to see other solutions in this space since coming across the react-ideal-image package a couple of years ago and this is definitely one of those solutions that stands a head above.
Resources and further reading
Image credit: bmarcel
See how you can dynamically create UIs based on React State using dynamic imports, Next.js 10 and React State
Have you ever wanted to build a UI Component Library with TypeScript and React? This blog post will take you through a straightforward set up that uses the bare minimum to get a working component library that you can re-use across your different React projects.
This post will go through a simple example of setting up simple authentication with a user and password to your Next.js website.
This blog post will explore the new internationalised routing in Next.js 10 and how you can use this to your advantage with react-intl for React.js
1,200+ PEOPLE ALREADY JOINED ❤️️
Get fresh posts + news direct to your inbox.
No spam. We only send you relevant content.