> Nowadays users browse the web using their phones, tablets, and laptops, yet images are still as a one size fits all. For example: sites load a 2000 by 2000 pixel image, but phones are only displaying it as 100 by 100 pixels.
That's what srcset & <source> were invented for.
> Furthermore, 30% of images on web pages are outside of the initial viewport, meaning the browser loads images that a user does not see until they scroll further down the page.
That's why we now have a loading=lazy HTML attribute
> When using the next/image component, images are automatically lazy-loaded, meaning they're only rendered when the user is close to seeing the image. This prevents loading that 30% of images outside of the initial viewport.
This has been done many times before. For images outside the viewport it's great; for images which are in the viewport, the browser isn't able to discover the image until the JS has loaded and decided which image size to fetch. In my experience this slows down the overall rendering of the page.
I see the Google Chrome team was involved in creating this component so I'd like to know what's different this time, because they have the data.
> Developers can mark images that are in the initial viewport, allowing Next.js to automatically preload these images. Preloading images in the initial viewport has shown improvements to the Largest Contentful Paint by up to 50%.
How can smart preloading work when the image size isn't known until the JS component runs? If we're back to loading the 2000px image then we're losing a lot of optimization.
If they're relying on client hints [1] then we can get as far as an image as wide as the browser window width, but no more - at the price of poor browser compatibility.
Preloading also has its own costs, as it messes with the browser's prioritization of page content. I've found it easy to prioritize something you know is essential and unintentionally increase load time metrics.
> That's what srcset & <source> were invented for.
Next.js is going to be using srcset under the hood, I'm sure. The whole point of Next.js is to make best practices like this defaults, not to do anything groundbreaking and new.
> That's what srcset & <source> were invented for.
next/image makes use of srcset.
> This has been done many times before. For images outside the viewport it's great; for images which are in the viewport, the browser isn't able to discover the image until the JS has loaded and decided which image size to fetch. In my experience this slows down the overall rendering of the page.
>I see the Google Chrome team was involved in creating this component so I'd like to know what's different this time, because they have the data.
No knowledge of what Google contributed to this, but my experience of running Google PageSpeed Insights on many sites is that this sort of optimization does improve the metrics Google measures.
Also, while I agree in part with most of your points, I still think we should give credit to nextjs for making this easy.
Sure, maybe you don't need a library to use srcset. If you are going to run our own custom build processes (or server endpoints) that generate images in a range of appropriate sizes and write the corresponding front-end code, good for you. Next.js has done nothing to stop any of this.
But many (most?) websites don't bother with any of that and just load one giant image for everyone. If there is a tool that makes using optimized images as easy loading one giant image for everyone, I think that's great.
I don't know Next.js but I just spot checked a comparison to see if srcset is an exact subtitute.
- If I'm reading CanIUse chart correctly, it says IE11 isn't compatible.[1]
- syntax of srcset requires manual and verbose specification of different source images. E.g. from MDN[2]:
<img srcset="elva-fairy-480w.jpg 480w,
elva-fairy-800w.jpg 800w"
sizes="(max-width: 600px) 480px,
800px"
src="elva-fairy-800w.jpg"
alt="Elva dressed as a fairy">
- Next.js example[3] is simpler and shorter:
import Image from 'next/image'
<Image src="/profile-picture.jpg" width="400" height="400">
The Next.js post also says that <Image> tag also provides the following dynamic feature: When using the next/image component, images are automatically lazy-loaded, meaning they're only rendered when the user is close to seeing the image. This prevents loading that 30% of images outside of the initial viewport.
Like I said, I'm not an expert. The Next.js Image function doesn't look like useless redundancy with plain HTML5.
Yeah, I mean, screw IE11 users. An unsupported srcset just means that they will not benefit from this enhancement but they will just download a standard size. This is perfectly fine.
As for the syntax, yes, it’s better to always have some generator to create it. WordPress has been doing it for years with a plain `the_image($id)` call.
A better way of saying this is that srcset gracefully degrades for IE11. They will miss out on the benefits, but they still get to use a regular <img /> tag.
> How can smart preloading work when the image size isn't known until the JS component runs?
From the article:
- Image dimensions are enforced, allowing browsers to immediately render the space needed for the image instead of having it jump in when loaded, preventing layout shift.
- While width and height on the HTML <img> element can cause issues with responsive layouts, this is not the case when using next/image. When using next/image the image is automatically made responsive based on the aspect ratio from the provided width and height.
Is srcset commonly used? I am not familiar with it but I'm more full stack than frontend and often feel like front end moves faster than I can keep up with.
I don't know about its popularity, but it works as advertised and my company had used it. What's more important is that it's a correct solution for the problem (unless old browser support is required).
Saying you have the only and first solution to a problem and having no comment section and never acknowledging people on twitter, hackernews and reddit.
That's what srcset & <source> were invented for.
> Furthermore, 30% of images on web pages are outside of the initial viewport, meaning the browser loads images that a user does not see until they scroll further down the page.
That's why we now have a loading=lazy HTML attribute
> When using the next/image component, images are automatically lazy-loaded, meaning they're only rendered when the user is close to seeing the image. This prevents loading that 30% of images outside of the initial viewport.
This has been done many times before. For images outside the viewport it's great; for images which are in the viewport, the browser isn't able to discover the image until the JS has loaded and decided which image size to fetch. In my experience this slows down the overall rendering of the page.
I see the Google Chrome team was involved in creating this component so I'd like to know what's different this time, because they have the data.
> Developers can mark images that are in the initial viewport, allowing Next.js to automatically preload these images. Preloading images in the initial viewport has shown improvements to the Largest Contentful Paint by up to 50%.
How can smart preloading work when the image size isn't known until the JS component runs? If we're back to loading the 2000px image then we're losing a lot of optimization.
If they're relying on client hints [1] then we can get as far as an image as wide as the browser window width, but no more - at the price of poor browser compatibility.
Preloading also has its own costs, as it messes with the browser's prioritization of page content. I've found it easy to prioritize something you know is essential and unintentionally increase load time metrics.
1. https://caniuse.com/client-hints-dpr-width-viewport