Contents
Overview
Next.js 10 was released on October 27, 2020, but the image display has become very convenient, so I investigated it.
* The surveyed version is 10.0.3.
What is Next.js 10 image display?
React Component is prepared as next / image, and it will be optimized automatically.
Previous way of place an image on the page
<img src="/profile-picture.jpg" width="400" height="400" alt="Profile Picture">
The new way of placing an image on the page using Next.js 10
import Image from 'next/image'
<Image src="/profile-picture.jpg" width="400" height="400" alt="Profile Picture">
About the function of next / image
Resize
Optimal file size depending on the viewport of your browser.
Image format conversion
Depending on the browser support status, the next-generation image format will be used.
Next-generation image formats are WebP, JPEG2000, and JPEG XR, which have smaller file size and higher expressiveness than conventional JPEG and PNG.
However, it was very difficult for developers to handle because the browser support status is different.
However, because next/image supports it, the developer does not need to convert the format, and the user can display it quickly.
About image format
https://websas.jp/column/developer-01
Support status of each format
https://caniuse.com/#feat=webp
https://caniuse.com/#feat=jpeg2000
https://caniuse.com/#feat=jpeg+xr
Can be optimized even if the image is in another URL
Resources such as images may be stored on the server for images.
Even in that case, next / image can be used.
You can set the URL path hosted in the next.js config file.
Optimize on request
Image optimization is done at request, not at build time.
The optimized image file is .next/cache/images
saved in the directory.
Cache
The optimized image file has an expiration date, and if it is within the expiration date, it will be reused.
If it is overdue, it will be removed before the new optimization.
The expiration date seems to refer to Cache-Control in the response header of the server that delivers the image, and if there is s-maxage, its value, if not, max-age, otherwise it is 60 seconds.
If you want to manage your images in next.js, you can change the expiration date in next.config.js.
Example of changing from 60 seconds to 5 minutes
module.exports = {
async headers () {
return [
{
source: '/(.*).(jpg|png)',
headers: [
{
key: 'Cache-Control',
value:
'public, max-age=300, s-maxage=300',
},
],
}
]
}
}
Lazy loading is the default
Lazy loading is a method of downloading an image when the user is close to where it can be seen.
You can avoid slowing down the display speed by downloading images that are not visible in the initial display.
* When I looked at the code, it was supposed to be downloaded when it was within 200px from the image file.
https://github.com/vercel/next.js/blob/v10.0.3/packages/next/client/image.tsx#L246
Launch sample code
I used this because the sample code is officially prepared.
https://github.com/vercel/next.js/tree/v10.0.3/examples/image-component
You can download it and launch it locally, but you can also check it here.
https://image-component.nextjs.gallery/layout-fixed
Images provided
Image file name | capacity | size |
---|---|---|
moutain.jpg | 294KB | 2800 x 1900 |
The code
import Image from 'next/image'
import ViewSource from '../components/view-source'
const Fixed = () => (
<div>
<ViewSource pathname="pages/layout-fixed.js" />
<h1>Image Component With Layout Fixed</h1>
<Image
alt="Mountains"
src="/mountains.jpg"
layout="fixed"
width={700}
height={475}
/>
</div>
)
export default Fixed
Operation check
Looking at the .next directory at startup, the images directory is not created.
When I accessed it with a browser, a webp image file was created.
If you look at the network of developer tools /image
, the parameters are passed to the entry point.
Parameters | Explanation |
---|---|
url | URL of the image file. Image src. |
w | Width after optimization. Select the optimal width from deviceSizes based on the props passed to the viewport and Image. |
q | Optimized quality. The default is 75, which can also be set with Image props. |
The file size of the downloaded webp is 6.7KB.
If you resize it with jpeg with a width of 750px with the preview tool of mac, it was 27KB, so it will be 4 times different.
If you have a site that displays a lot of images, the page display speed can be improved considerably.
The behavior of each browser
It is said that it will provide the optimum image for each browser, so I tried it with various browsers.
browser | Image format | Image width | Download size | Supplement |
---|---|---|---|---|
iPhone11 Pro Safari | webp | Original width | 152KB | |
Android chrome | webp | Original width | 156KB | |
mac chrome | webp | 750px | 18KB | |
mac safari | webp * Depending on the OS version, it may be jpeg | 1920px and original width | 74KB and 152KB | There seems to be a bug that downloads twice. https://github.com/vercel/next.js/issues/19478 |
Windows IE11 | jpeg | Original width | 255KB | |
Windows Edge (Chromium) | webp | 750px | 18KB | |
Windows Firefox | webp | 750px | 18KB |
Since the width is set to 700, 750px, which is close to that, should be downloaded, but is it a bug that the original width is downloaded?
When downloaded with the original width, the parameter w was 3840, which is the maximum value of deviceSizes.
It’s best to fix the bug, but as a temporary workaround, I don’t think there are many sites that require a width of 3840px, so it’s a good idea to change deviceSizes in next.config.js. That’s right.
When the original image is png
I’m talking about webp, but I was also interested in png, so I collected some images and checked the effect of optimization.
The width of the image has not changed.
Original size | Size after webp |
---|---|
242KB | 27KB |
239KB | 44KB |
23KB | 4KB |
176KB | 31KB |
84KB | 24KB |
Depending on the image, it has been reduced to about 1/4 to 1/9.
You can also reduce the size of png considerably.
Why next / image was created
Since CLS is mentioned in the official Next.js documentation, it is likely that you are considering Core Web Vitals.
Core Web Vitals are three performance indicators, LCP, FID, and CLS. If you download a large image or if the layout position shifts when the image is displayed late, it will have a bad effect.
Google has announced that it will be included in the search ranking index from May 2021, making it a very important index.
About Core Web Vitals
https://www.sakurasaku-labo.jp/blogs/core-web-vitals
Summary
next / image is feature-rich and convenient, but it also has a lot of Props and requires a little learning.
Since the influence of Core Web Vitals will come out in May 2021, if you are using Next.js, I think that it is better to import version 10 as soon as possible.
References
- About Image Component
https://nextjs.org/docs/basic-features/image-optimization - Image Component API Specification
https://nextjs.org/docs/api-reference/next/image - Image Component sample site
https://image-component.nextjs.gallery/ - Image Component sample code
https://github.com/vercel/next.js/tree/v10.0.3/examples/image-component - PNG image material
https://ja.pngtree.com/
Author: matsu012 from Qiita
Discussion about this post