How Nextjs Image is so optimized

8th November 2022

0

Page Index

    Share

    Introduction

    Nextjs Image is so optimized that it loads almost instantly after the first time. Next is doing a really great job behind the scenes regarding the type of image files and quality of the same and decides at which quality it should be rendered. Yes, even though the image might be 4K, its not rendered in 4K.

    Looking at the Code

    We can download the code of Nextjs from its github repo and take a look at the image component image.tsx. The associated files would be image-optimizer.ts and image-config.ts

    image.tsxpackages/next/client/image.tsx

    image-optimizer.tsxpackages/next/server/image-optimizer.ts

    image-config.tsxpackages/next/shared/lib/image-config.ts

    From the path itself, it is known that image.tsx is for client side and the optimizer is for server side.

    Client Side

    Just a reminder that Image component takes a lot of props.

    ✅ For different layouts, Next set different sizes in terms of width and height.

    ✅ Next checks if there is blur option from user. If there is, it sets the blur image as the user provided one and if not, it sets its own.

    ✅ If src starts with ‘data:’ or ‘blob:’, it is set as unoptimized, shown as raw image

    Errors for LCP, not providing width and height, not providing src etc are handled beautifully

    ⚡ For priority mode images, they should be loaded lot faster. Next does this by adding a Head tag with rel="preload" along with rendering image

    ⚡ Behind the scenes, the img tag make use of a useCallback of a function which handles loading, taking dependencies as src(attr), placeholder(attr), onLoadRef(fnc), onLoadingCompleteRef(fnc), setBlurComplete(fnc), onError, unoptimized(attr

    ⚡ When it comes to large resolution images, Next only shows 2x resolution; i.e. 2x2 pixels per dot of resolution, because 2x is the max resolution a human eye can get the details from. Even if the details were 3x, humans cannot see that LOD through it and it consumes a large amount of data. This means, whatever the width that the user gives as attribute to the image component, the maximum resolution that Next would render is 2 times the width. If 250 is the width given, max of 640px would be rendered (2x would be 500. 640 is the next possible standard screen resolution)

    And many other things are going on in the client side.

    Server Side

    ✅ Server side make use of Sharp, an image processing package, which is faster and lighter for processing images. Sharp has a lot and lot of methods for manipulating the image in whatever we want the image to be. You might wanna check the methods that are available, they are really cool

    ✅ Then, making use of a package called Squoosh, another cool image processing package, Next handles the processing of images with desired quality depending on the type

    ✅ After all the processing, headers like cache control, content disposition, content security policy, ‘X-Nextjs-Cache’, content type, content length etc are sent along with the response. The important thing to mention is that almost all file types are converted equivalent to that of webp for more optimized loading

    ⚡ When server calls the ImageOptimizerCache (which is the class name for image-optimizer), the image(s) is processed first like mentioned above and are cached inside ‘_next/image’, which is done by ImageRouting function inside server. Any stale cache are periodically removed by Next itself

    Error Handling

    All types of error cases, for width, height, src, srcSet, blurImage, onLoad, onLoadComplete, wrong path etc are handled by the Next beautifully and it can be understood if you look the code itself.

    Handling width property associated with fill attribute

    Error code example

    Handling src attribute

    Error code example

    Handling width and url properties

    Error code example

    Concluding

    Combine the server actions with the front end actions, you get beautifully optimized Image component, which delivers super fast image loading time and cached response. Thats how Nextjs <Image/> works.

    About the Author

    Related Blogs

    View All Blogs
    No blogs!

    Want #swag?

    Join our monthly raffle!

    Every month, One Lucky Duck gets free swag shipped to their doorstep, wherever in the world you are! All you have to do is join our Discord channel today and tweet about the amazing things we do. #nullcast #luckyduck

    We will announce the winners on Twitter and through our discord channel.

    Duck