Next.js Image in-depth tutorial

  Рет қаралды 26,992

Full Stack Zach

Full Stack Zach

Күн бұрын

#nextjs #nextjsimage #vercel
The Next.js Image component is super powerful, yet can be costly if misused. This tutorial walks you through the most important concepts behind this component and aims to show how to use this in different situations.
Supplementary repo:
github.com/zachgoll/nextjs-im...
Chapters (skip to the one you're interested in!):
0:00 Intro
6:21 Why should you care about Next.js Image (and images in general)?
16:35 Large images DESTROY your Lighthouse score (and how to fix it)
24:26 A costly $$ mistake with Next.js Image (hint: you might need a custom "loader")
35:53 How to use Next.js image effectively
37:00 Static (local) image usage
39:40 CLS and why Next.js Image REQUIRES a width and height
42:46 What is a LQIP (low quality image placeholder)?
48:08 How to generate your own LQIPs for remote images
57:11 What if I don't know the width/height of my image?
1:02:50 How to make your images responsive with `fill` property (no width/height required)
1:06:40 Why "srcset" and "sizes" props are SUPER important
1:30:35 Brief migration guide from next/legacy/image to next/image
Resources I mentioned in the video:
- nextjs.org/docs/api-reference...
- developer.mozilla.org/en-US/d...
- www.mydevice.io/
- developers.google.com/speed/webp

Пікірлер: 97
@RaulReyesOnline
@RaulReyesOnline Жыл бұрын
This is hands down the best explanation I had ever found on the internet. Not exaggerating. The use of the references and the comparisons when need it are pure gold. It is done with a humble approach to teaching rarely found on KZfaq amazing! Makes me feel human…thanks!
@zachgoll
@zachgoll Жыл бұрын
Thank you! I put a lot into this one :)
@weekendcode
@weekendcode Жыл бұрын
Benefits of this video 1. suggests examples after viewing the official documentation 2. teaches you things that are not in the official documentation 3. configures multiple components to show contextual implementation 4. goes inside the class to see how the internal properties are organized
@ozzyfromspace
@ozzyfromspace 9 ай бұрын
Feedback: I watched your video with a high degree of focus, in fullscreen mode, in one sitting (you held my attention really well!). The patience, detail, and clarity with which you went through the image component was exceptional. Overall, this was a phenomenal lecture, and really brought to light a few things I didn't understand. 10/10, liked and subbed! And I'll be sure to recommend your video to my NextJS friends :) Thank you so much, Zach! Also, you asked a question about clarifying sizes and srcset: Basically, srcset allows you to provide a list of url's for your images that should execute when the image reaches a certain width. For instance: "/path/to/a 400w, /path/to/b 800w" would load the first image while the browser expects the image to be under 400 (computed) pixels (not hardware pixels), and the second image would load once the browser expects the image to have a width over 400 pixels and under 800 pixels. The little detail here is that the browser is actually looking for the width of the image, not the viewport. So, ofc you can think of "400w" as the width of the viewport, but really it's the expected size of your image. They just happen to be the same. But this is where the "sizes" prop comes in. In srcset, above, the browser computes the expected size of the image by ASSUMING that the image will take up the full width (i.e. 100vw). It does this because you might, for example, have some fancy css going on with flexbox or grid etc, so it doesn't know how you wish to actually render the image. For example, you could render an image in a 2-column layout. The browser doesn't know, because it can't statically analyze your codebase. So it assumes that the width of the image is 100vw, the width of the viewport. So sizes essentially allows you to tell the browser how much width the image will take in your layout. For example: sizes="50vw" is telling the browser that the image has a width that is 1/2 of the viewport width. So If your viewport has a width of 1240px, the browser knows that your image is expected to take up half of that (50vw = 1240/2px = 620px). So at a width of 620px, the browser can THEN look at the srcset to figure out which url to use based on what interval the 620px image is in. While you may not have been super confident about this perspective in the video, you actually managed to demonstrate it correctly, and ultimately gave us the right idea. This text is merely intended to state the relationship between srcset and sizes more clearly, and validate what your experiments suggested, because ultimately you were right that sizes maps to some fraction of the width's in the srcset. So, amazing job! Bonus: sizes can actually take a calc, so if for whatever reason you needed to be more specific/accurate about the amount of width in the viewport that the image takes up, you could compute it. For example, say you have a 2 column grid whenever the viewport exceeds 600px, and the grid has a gap of 8px. Further, the horizontal padding on either side of the container is 12px. Then assume that you want to place an image in one of the grid cells. Then you might do something like: sizes="(max-width: 600px) 100vw, calc(50vw-8px-2*12px)". This says up to a maximum width of 600px, assume the image has a width of 100vw. If you can't find a media query to satisfy the current screen size, default to the calc, which is essentially 50vw, less the padding-x of 2 * 12px and the gap between the left and right columns of the rgid: 8px. Hopefully you find this excerpt useful. It's a lot of writing but I think it's worth it, considering just how much time and effort you put into this amazing video. Thanks, and best wishes mate! - Oz.
@zachgoll
@zachgoll 9 ай бұрын
Well said! Great explanation, and glad you found the video useful :)
@dopetag
@dopetag 11 ай бұрын
The way you explain everything is outstanding! This was so comprehensive that all the questions dropped during watching.
@jmg9509
@jmg9509 10 ай бұрын
I cannot thank you enough for this amazingly detailed guide. And yes, things did indeed finally click...I can finally get my image file size tiny enough to not bog down my app. Before, I see now, that I was loading huge desktop file sizes for even mobile devices. Don't mind my referencs below (for when i need to get a referesher :) ) 1:15 - Questions I been banging my head on the table about 14:10 - with sizes - the image size reduces drastically (more than 10x) 16:35 - 3. What does Image Optimization/transformation mean? 26:50 - Loaders 36:30 - 5. How to effectively use Next.js Image in diff situations 42:30 - placeholderBlur & blurDataUrl explained 49:30 - calculate blurDataUrl yourself (for remote images) 1:12:10 - sizes explained indepth 1:19:50 - sizes - local images require sizes if 'fill' is not specified, in order to generate a srcset
@sylvainschellenberger
@sylvainschellenberger 9 ай бұрын
Thank you for taking time to put up this in-depth tutorial. This was very well needed to cover this topic that can be easily overlooked. Nice job!
@simenhagen86
@simenhagen86 Жыл бұрын
Thanks for this, came here from your photography guide. really like the way you teach. done the front end course that you had on FCC and loved it also. still not able to make something on my own, but hopefully get there.
@EmpySoul
@EmpySoul 8 ай бұрын
Man! This is a awesome guide!!! I totally recommend watch this video if u wanna know how to use Image component. I did not know about the pricing for more than 1k photos. U saved my as* Thanks!!!!
@phuphan8672
@phuphan8672 11 ай бұрын
NGl, I rarely comment on KZfaq, but your video is so amazing! The way you prepared demos and explained everything is done very well. I learned a lot from it and watched until the end without skipping a second. Thank you so much for this outstanding video.
@SuperValza
@SuperValza Жыл бұрын
Great video. Watched twice. Improved my pictures sizes from 1mb+ till around 50kb-100kb and still did not fully understood sizes section, so I guess I have place for improvement more. Thanks a lot. Keep up good work.
@ramiro041
@ramiro041 10 ай бұрын
I'm glad you undertook the efford of making this video, it made things very easy for me
@aleksandercross5936
@aleksandercross5936 3 ай бұрын
Thank you very much, this part 1:02:50 "How to make your images responsive with `fill` property (no width/height required)" is exactly what I was looking for.
@patite3103
@patite3103 Жыл бұрын
Could you please update the video to the new version Nextjs 13.4? thank you
@ShubhamSinha90
@ShubhamSinha90 Жыл бұрын
One of the best in-depth tutorials ever.
@zachgoll
@zachgoll Жыл бұрын
Thank you! It’s the tutorial I wish I could have found for myself.
@exterminate1482
@exterminate1482 Жыл бұрын
Thanks for an amazing tutorial! Just want to add some explanation of `w` size. There is a prop in `window` object which is called `devicePixelRatio`. The value of this prop depends on scale of 'resolution'. For example in windows this setting is called 'Scale and layout' and you can set some percentage value like 150% and it will be equal devicePixelRatio = 1.5. So 800w is equal 800px / devicePixelRatio, in your device 800w is equal 400px.
@zachgoll
@zachgoll Жыл бұрын
Awesome, thanks for this!! Makes a lot more sense than what I was fumbling through in the video :)
@arisudana3672
@arisudana3672 Жыл бұрын
My good sir you quite literally saved my life with this video. Thank you so much
@cherkim
@cherkim Жыл бұрын
Just what I needed. TY!
@saadbaig3060
@saadbaig3060 Жыл бұрын
Very well explained! Thanks.
@issussov
@issussov Жыл бұрын
Pretty cool video! Kudos to you Zach!
@user-vg6ot5fy9b
@user-vg6ot5fy9b Жыл бұрын
Exactly what I am looking for........thanks a lot for sharing this
@jarnoojasaar
@jarnoojasaar 11 ай бұрын
finally got my sizes property working, thanks alot. had to statically import my local images instead of just having "src='images/sample.jpg'"
@gabrielgomesmabiala6707
@gabrielgomesmabiala6707 11 ай бұрын
Your channel is so underated thank you so much for this tutorial Just keep on
@kevinhe8188
@kevinhe8188 Жыл бұрын
Hope you can make more and more like this. very enjoying watching. Super video u made. which really clear explain.❤
@mohamedyoussef8835
@mohamedyoussef8835 4 ай бұрын
Hi Zach... Best explanation on KZfaq... You really research and you REALLY know how to explain +++++
@krzysztofs3t532
@krzysztofs3t532 4 ай бұрын
1:13:40 - I think Next download 800+ pixels image version not because of pixel density of your screen, but because you have your image styled as objecy-fit: cover. So - your screen is 400px wide, but you see only a center part of the image, because it is in a cover mode, the original image have about 800-900px width. There is no technology yet to cut part of the image in a flight and load only this part that you actualy see. Great video BTW.
@ramkumargurav9829
@ramkumargurav9829 Жыл бұрын
thanks man I just learned how to make my image card with this,
@GonzaloBetancourt
@GonzaloBetancourt Жыл бұрын
Gold content, Zach 👏👏👏
@flnnx
@flnnx 5 ай бұрын
Top notch content. Thank you!
@sincethatmoment
@sincethatmoment Жыл бұрын
amazing job. you speak very well and explain clearly. thanks for sharing. I would have never known about the pricing
@zachgoll
@zachgoll Жыл бұрын
The pricing is not very transparent, wanted to shed some light on it!
@soroushebi
@soroushebi Жыл бұрын
thanks a lot for the video. great job !
@TheHoinoel
@TheHoinoel Жыл бұрын
this is excellent. thank you
@DiXXOver
@DiXXOver Жыл бұрын
Thank you very much, you saved me a lot of time
@27sosite73
@27sosite73 8 ай бұрын
again thank you so so so so so much!
@nathanbrachotte
@nathanbrachotte 10 ай бұрын
Pure gold.
@mounsifcherfaoui121
@mounsifcherfaoui121 Жыл бұрын
What a great video 👏
@andrewpaulhart
@andrewpaulhart Жыл бұрын
Thanks so much for posting this video. I was going around in circles trying to get my images to behave properly.
@zachgoll
@zachgoll Жыл бұрын
Same haha, created this tutorial after I walked in circles for too long
@zachgoll
@zachgoll Жыл бұрын
Also just noticed you made a contribution to the channel! (Not sure how I missed this) Thank you 🙏
@andrewpaulhart
@andrewpaulhart Жыл бұрын
@@zachgoll you are welcome. I always try and show just a tiny bit of appreciation when someone takes the time and effort to provide something of value
@en_kratia
@en_kratia 7 ай бұрын
Thank you very much
@eyenfernandotuyon5075
@eyenfernandotuyon5075 4 ай бұрын
Its a very very great video very well produced and explained. Thanks for saving us a lot of time. Btw I have a few questions. What is the limit of size of an image can be reduced in the height width mode? For example: I have a image with the resolution of 300x1200 and I want to reduce his size putting in the Image component w=50 h=50 and this give me an error. Is beacuse the images has a limit ? Or is for the aspect ratio?. Another thing. How the zoom in and zoom out affects the requests of the image that's has the fill mode?.
@namelastname4604
@namelastname4604 Жыл бұрын
Nice presentation. Easy to follow. I wander why official documents do not explain it as well as in this video? At least give links to fill knowledge gap.
@user-qu8hg3wt3i
@user-qu8hg3wt3i 4 ай бұрын
Thanks for sharing. I am confusing about what different between put all images in source code and in public folder
@8koi245
@8koi245 Жыл бұрын
Ahhhh I'm exactly in that point, found it out to be pretty cool but I really want to understand what it does and why
@utvecklarakademin
@utvecklarakademin Жыл бұрын
Super great stuff, I think this video should be highligted by the nextjs team! Please timestamp it though, I think that helps a lot when the length is so long. Cheers
@zachgoll
@zachgoll Жыл бұрын
It should be timestamped already, is it not showing up? Edit: you’re right! They aren’t showing up, I’ll fix that. They are in the description right now. Thanks for the heads up!!
@utvecklarakademin
@utvecklarakademin Жыл бұрын
@@zachgoll Glad to help :-) Keep it up!
@Light-nn6hn
@Light-nn6hn Жыл бұрын
how do i add a blurry placeholder when using the fill propety, it just doesn't seem to work, also, is there a way i can keep the aspect ratio of the image when setting the fill property, object-contain works, but it won't fill the whole container of the image.
@madashindeinai4783
@madashindeinai4783 5 ай бұрын
This is a fantastic guide. I really regret that I found it so late. It could have saved me a lot of time. The video gives an understanding of how to test behavior, and the opportunity to independently find answers to the remaining questions (fill + sizes). The only not really covered question: we can add a local image via import (like in a video), but we can also simply provide a link to the image in the public folder (
@zachgoll
@zachgoll 5 ай бұрын
When you import the image, Next.js will infer the dimensions and build the "blur" image to use automatically for you. If you simply provide a relative path, none of this will happen since it will be treated as a "remote" image (with your domain as the base of the URL) In other words, importing is the better option here in most cases.
@jirifiala2811
@jirifiala2811 Жыл бұрын
Thanks for the tutorial. Could you provide a link to this project git repo?
@zachgoll
@zachgoll Жыл бұрын
My bad! Had meant to add that to the description. Here's the link (also added to description): github.com/zachgoll/nextjs-image-tutorial
@kayuxcodes
@kayuxcodes 2 ай бұрын
its seems that next.js fetch the image based on the viewport width, in your example 1:16:35 sizes are set to 100vw so it will take the full width, so why the image is fetch the 750w is that the next.js will take the deviceSizes and find the first width that is closer to the DPR, so 750 / 292 == 2.5
@sergey_gabrielyan1001
@sergey_gabrielyan1001 4 ай бұрын
Hello👋. I have a project with plain React and Supabase (also I’m using supabase storage), I’m trying to find the best option to make image optimization, but as I understand it’s difficult to do that with plain React. I want to use srcSet option which has a Next.js with automatic way. I know that there are services like imageKit, imgix, cloudinary…, but it will be better to do that without external services. If it’s not difficult can you give me advice, how can I make image optimization, which way is common in plain React?
@harrysaladfingers1515
@harrysaladfingers1515 Жыл бұрын
I'm using wasabi to serve my remote images and turnsout blurdataUrl and the imgsrc loads at the same time so it's making no visible difference. There's a white space for quite some long. Pls help
@joemart6887
@joemart6887 9 ай бұрын
What if you add the 'unoptimized' property without a loader to the Image component? How will this behave within NextJS? Will NextJS use their loader? Will we be using their services if we have a the 'unoptimized' property enabled without a loader?
@NetraPatwari
@NetraPatwari 6 ай бұрын
Thankyou
@phantazzor
@phantazzor Жыл бұрын
was waiting for the lazy load
@jrmartinss
@jrmartinss Жыл бұрын
One interesting thing I would like to see is to create a dynamic src. For example, for web would be an image and for mobile devices would be another, I already tried using useEffect, but it loses the performance of the Image component
@zachgoll
@zachgoll Жыл бұрын
I think in that scenario, the best approach would be to create 2 separate image elements and use CSS media queries to hide or show each of them depending on the screen size. Something like this (using TailwindCSS): ``` ```
@farhadvakilijamil2987
@farhadvakilijamil2987 9 ай бұрын
Hello. How are you. Bro I have an issue. I can't display product images by maping in component inside Image Tag. does this course help me to solve my problem?
@carlopelosi5251
@carlopelosi5251 9 ай бұрын
Seems that even after using, sizes prop and fill, can never get the image perfect for Google Site Speed to not complain?
@user-uo3sg4bn3y
@user-uo3sg4bn3y 3 ай бұрын
So What I'm facing an issue is I'm loading banner images by using json so basiclly there is dyamic pages So the issue is, It showes white screen with text on banner then after 1 or 2 sec image loads with proper banner with text , But the Image size is 500kb. Please give me the solution what should I do.
@0r1x
@0r1x 9 ай бұрын
How are you loading without using a width property. In every project I use, the console fails and requests a width and height property.
@OddRob92
@OddRob92 Жыл бұрын
Is a repository similar to a suppository.
@utvecklarakademin
@utvecklarakademin Жыл бұрын
Tbh skeleton loaders are much better UX than blur images in my opinion, what do you think?
@zachgoll
@zachgoll Жыл бұрын
I definitely prefer the blur placeholder, but in this case they would actually be similar solutions from a performance perspective. The only difference is that you’d have a gray placeholder data url for the skeleton placeholder which does have the advantage of not having to preload everything (assuming you have a way to dynamically size the skeleton loader placeholder)
@suyashsrivastava3671
@suyashsrivastava3671 11 ай бұрын
24:30 that's what nobody is talking about, we need to deploy on vercel to automatically get our image optimized and that's freemium service .
@power-tools
@power-tools Жыл бұрын
Are you talking about Nextjs 13?
@carlopelosi5251
@carlopelosi5251 9 ай бұрын
Hey Zach! I just sent you an email about this Next JS Image component Thank you very much for this video it cleared up a TON of what I was running into. Though I still have one issue, but 9/10 of my issues have been solved with this. I'm extremely interested in finding the solution. Would love your insight here. Im seeing Largest Contentful Paint element 3,090 ms This is the largest contentful element painted within the viewport. Learn more about the Largest Contentful Paint elementLCP But the image is 400KB and I have tried. Fill and Sizes, Normal width/height. Some others as well. Curious on why I can't seem to fix this
@user-xr4oo2xp7q
@user-xr4oo2xp7q 5 ай бұрын
Doesn't works with other hosting providers other than Vercel also?
@zachgoll
@zachgoll 5 ай бұрын
Yes it does! It's a generic React component, but if you host on Vercel, it automatically opts in to the image optimization API (unless you use remote images)
@user-xr4oo2xp7q
@user-xr4oo2xp7q 5 ай бұрын
@@zachgollI see. So, how does it optimise in other hosting providers, I wonder?
@zachgoll
@zachgoll 5 ай бұрын
@@user-xr4oo2xp7q By default, it will not. If you are using a remote source, you’ll need a loader to set dimensions and do image transformations. Check out the loader chapter of this video to dig deeper on that concept
@dvkerns
@dvkerns Жыл бұрын
1:23:40 It grabbed the 96 because you're viewing on a 2x device, so...closest to 50px * 2 ?
@zachgoll
@zachgoll Жыл бұрын
Must be! Tbh, still a bit confused myself about how the user agent chooses (not Next.js Image). I think the 2x rule is probably correct though, yes. Did quite a bit of research, couldn’t find much other than “user agents choose differently based on all sorts of factors like device size, pixel density, etc.”
@denisvradiy8503
@denisvradiy8503 Жыл бұрын
Not sure you're correct because 50 * 2 = 100. [16, 32, 48, 64, 96, 128, 256, 384] - imageSizes array. So if 50 * 2 = 100 then it should load 128, but not 96, because 96 value has already been passed.
@zachgoll
@zachgoll Жыл бұрын
@@denisvradiy8503 I think David’s explanation makes sense. You’d always want to load an image that is slightly larger than the viewport, so in this scenario, 100 is the closest number to 96 that is still larger
@Miodragrrr
@Miodragrrr Жыл бұрын
Tell me if i got this right. So you have a non-commercial pet project so you just want to use free plan for image optimization, with nextjs image component Vercel is default image optimizer up to a 1000 original images for free? After that it's costly. So instead you put unoptimized prop to an image component and now it isn't using anything for optimization unless you build your own custom loader. So you did that using unsplash api, which is using other author images on unsplash site. If i have my own images (and don't want them on unsplash site) which cdn/api you prefer/propose to achieve same ability and stay within free plan, of course not indefinitely, but lets say with a budget friendlier option?
@zachgoll
@zachgoll Жыл бұрын
You almost got it. When you set the unoptimized prop, no matter what, no images will be optimized. If you’ve got your own images that you want to optimize-either deploy to Vercel and use the default loader OR write your own custom loader and use a platform like Imgix or Cloudinary.
@user-fj9om4qy2k
@user-fj9om4qy2k 6 ай бұрын
you dont need to import image from "public" dir. just use it in src like src="/whatever.jpg"
@zachgoll
@zachgoll 6 ай бұрын
This works, but you won’t get the benefits of the optimization API. When you statically import as I show, Next.js will infer the dimensions of the image which helps with CLS (cumulative layout shift)
@abhishekthammali5530
@abhishekthammali5530 Жыл бұрын
can you teach react js
@zachgoll
@zachgoll Жыл бұрын
Possibly a future video series! That’s a tough one for me because it will become a very long series, but will definitely keep in mind.
@bharatmankotia4319
@bharatmankotia4319 Жыл бұрын
is next.js element a paid service ?
@zachgoll
@zachgoll Жыл бұрын
The Image component is not, it's just a normal React component. That said, if you deploy your Next.js site to Vercel, *by default* you are opted into a "freemium" image optimization service. You get 1000 unique source images per month for free and then after that you need to upgrade to Vercel premium.
@deepeshmhatre4291
@deepeshmhatre4291 Жыл бұрын
This video made me more confused
@zachgoll
@zachgoll Жыл бұрын
What about it? Specific parts I could address for you?
@deepeshmhatre4291
@deepeshmhatre4291 Жыл бұрын
@@zachgoll The part where you start saying Image component is a paid API. In the NextJS docs they refer no such thin, its confusing.
@zachgoll
@zachgoll Жыл бұрын
The image component itself is 100% free. It’s just an open source React component. That said, it makes API calls to a “freemium” image optimization service owned by Vercel, which allows for 1,000 source images free, then you’ll be charged. This optimization is enabled by default, so my goal with this video is to point this fact out. I do not think the Vercel docs emphasize this fact enough, which is why I emphasized it so much in the video.
@edhahaz
@edhahaz 11 ай бұрын
Holy shit it's a Vercel SERVICE and not actual code running on the server ? cash grab
@joemart6887
@joemart6887 9 ай бұрын
I'm having a hard time understanding your custom loader @33:02 . On line 9, what is src? Isn't that the first letter of the string? So, if you have "www.google.com", isn't src[0] in this case just the 'h'? My brain may be fried, so I do apologize if I'm not getting it. What is 'src.slice(1)' returning? I'm very confused on what you did here.
Why You Should Always Help Others ❤️
00:40
Alan Chikin Chow
Рет қаралды 123 МЛН
World’s Deadliest Obstacle Course!
28:25
MrBeast
Рет қаралды 90 МЛН
UI Libraries Are Dying, Here's Why
13:28
Theo - t3․gg
Рет қаралды 269 М.
How to Intercept Routes in Next js | Image Gallery
34:09
Cand Dev
Рет қаралды 3,2 М.
Using Images in Next.js (next/image examples)
9:10
leerob
Рет қаралды 92 М.
You're Doing Image Rendering WRONG in Next.js!
22:06
Sonny Sangha
Рет қаралды 59 М.
Why you SHOULD deploy to the edge
12:06
Ben Holmes
Рет қаралды 53 М.
All 29 Next.js Mistakes Beginners Make
1:45:10
ByteGrad
Рет қаралды 67 М.
Ждёшь обновление IOS 18? #ios #ios18 #айоэс #apple #iphone #айфон
0:57
Настоящий детектор , который нужен каждому!
0:16
Ender Пересказы
Рет қаралды 435 М.