Replies: 60 comments 100 replies
-
I'd like to see an example on how to use this with a hosted image solution like Cloudinary, Imgix, etc. |
Beta Was this translation helpful? Give feedback.
-
Wondering if a ratio is provided ahead of time, if this can be passed in instead of width/height. Our CMS gives us those fields. And by virtue of responsive design, that image probably won't be rendered at the resolution its given. |
Beta Was this translation helpful? Give feedback.
-
@atcastle amazing RFC! Will the FWIW then React Native's |
Beta Was this translation helpful? Give feedback.
-
Regarding height and width, as this meta data is available at build by fetching the image could we simply “inject” these values rather than require the developer to manually enter. This would allow for incremental builds where images are added dynamically or when images are updated but the developer forgets to update the values in the code. |
Beta Was this translation helpful? Give feedback.
-
Just wanted to note if this was to support |
Beta Was this translation helpful? Give feedback.
-
Great RFC 🙌 What is the strategy to lazy load the images? Is this not recommend using this component? |
Beta Was this translation helpful? Give feedback.
-
This is amazing! We have a custom <Image src={url} format="png" /> And this just appends |
Beta Was this translation helpful? Give feedback.
-
I'd like to know if is possible to add the option to add background css properties.
The prop |
Beta Was this translation helpful? Give feedback.
-
What about different image formats support? Currently Safari is lacking support for webp. It can be solved with different sources is there any plan regarding this? |
Beta Was this translation helpful? Give feedback.
-
I might be missing something big here, but I can't remember the last time I had a use case where hard-coding image width and height was a reasonable approach for any project, given the existence of responsive design. I feel pretty confident that if you are able to hard code an image's dimensions, and have those same dimensions work on both desktop and mobile views, that would be more of an edge case than the inverse. Aspect ratio, on the other hand, is definitely something that could be hard-coded and would in most cases be able to persist across screen sizes. Maybe this would be a better option? |
Beta Was this translation helpful? Give feedback.
-
This is super exciting and would definitely be another boon to the Next.js ecosystem. It would certainly replace/augment some of the makeshift solutions I have in place for my site. One thing I’d perhaps want to see added to the RFC is detail about the resulting output, and how it may differ from client to server (for example, what |
Beta Was this translation helpful? Give feedback.
-
OMG but the automatic srcsets means that I'll stop get manually the image size for each of my favorite breakpoints 😱 |
Beta Was this translation helpful? Give feedback.
-
I wanted to suggest that |
Beta Was this translation helpful? Give feedback.
-
Webpack plugins are designed to resolve paths to static assets relative to your current file, and do things like change the host to a CDN in a production bundle. It’s unclear to me why Next hasn’t embraced this and still relies on string paths to resolve files. I’ve set up my project to use require() to ensure static asset presence. Will the features of this component work if we do |
Beta Was this translation helpful? Give feedback.
-
This is really nice to see and I think having a I worked recently on a solution for serving well optimised images for a statically built Vercel + Next.js site. Here's a summary of my solution based on my particular use case, this might be useful as prior art / user story :
There is quite a lot of different parts to what I've written here in describing my use case and solution, and not all of the things on this list are in the scope of this RFC, but I kept them in anyway since they are at least tangentially relevant (and therefore should somewhat inform the API design). I will give some thought to how the solution described in this RFC would apply to my use case described above, and will write in this thread if I can think of anything that might prevent me from switching to using a If there are any parts of my solution that you think are nice then please feel free to steal my ideas. (The |
Beta Was this translation helpful? Give feedback.
-
Hey, does anyone encounter this problem when migrating from 10.0.0 to 10.0.1? |
Beta Was this translation helpful? Give feedback.
-
Is there a solution for using completely different images for different layouts? My current code:
|
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
are regular expressions currently supported in domains configuration? |
Beta Was this translation helpful? Give feedback.
-
Wondering what's the story for SSR support of |
Beta Was this translation helpful? Give feedback.
-
please provide a way to remove the wrapping |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
Hi, is there a way to make Image from next/image a link? Something like |
Beta Was this translation helpful? Give feedback.
-
My Image quality is not as good as it should be, you can see this hero image here: https://vv.test.tbstaging.dev/rs . I added quality={100} but it didn't improve much. This is the image that is comming from api: https://vvapi.test.tbstaging.dev/storage/600af708e75249.20195232/600af708e75249.20195232.jpeg |
Beta Was this translation helpful? Give feedback.
-
Hi, I finally tried this amazing component and I'm very happy with it! With the custom loader I can use my own service and the layout fill with ovject-fit cover is very powerful! Just a note: the resulting srcset count are always equal to the widths set on the config, even if my image is more little then the biggest size. It will be useful specify the sizes as Image prop too for a more granular result and less code in page... What do you think? |
Beta Was this translation helpful? Give feedback.
-
The Image Component has some very good things, but then there are few I don't like so much:
|
Beta Was this translation helpful? Give feedback.
-
Does the image component support gif images? (I cant make it work) |
Beta Was this translation helpful? Give feedback.
-
Guys in nowadays, which one is the best approach to pre-load images in Next.js? |
Beta Was this translation helpful? Give feedback.
-
Update: We have extracted the core logic from This allows usage outside of
Exampleimport { unstable_getImgProps as getImgProps } from 'next/image'
export default function Page() {
const common = { alt: 'Hero', width: 800, height: 400 }
const { props: { srcSet: dark } } = getImgProps({ ...common, src: '/dark.png' })
const { props: { srcSet: light, ...rest } } = getImgProps({ ...common, src: '/light.png' })
return (<picture>
<source media="(prefers-color-scheme: dark)" srcSet={dark} />
<source media="(prefers-color-scheme: light)" srcSet={light} />
<img {...rest} />
</picture>)
} PR: #51205 |
Beta Was this translation helpful? Give feedback.
-
I am trying to make Image component to resize my local images based on the prop sizes' value:
The author of the article mentioned "Out-of-the-box image support for new developers". I can't find anything about it. |
Beta Was this translation helpful? Give feedback.
-
(Note: Edited with annotation about how the next/image component has changed during and after the course of development. Last edited 3/10/21)
This RFC describes a #proposed custom image component to be built into the Next.js framework. This is a significant addition to Next.js, and has the potential to have large impacts on application performance outcomes and developer experience.
The objective of the component is to improve performance of Next.js applications at an ecosystem level, with a particular focus on improving their Core Web Vitals scores. The component is structured around the following three primary design concerns:
The image component provides an attractive developer experience
This is listed first because the other, performance-based design concerns are only effective to the extent that people actually adopt the component and benefit from its performance optimizations. Thus, the component should be:
Easy to use, with a concise and intuitive API.
Easy to refactor into existing pages--it should be able to coexist on a page with regular image tags.
Attractive as part of the new-developer experience. Getting developers using the component early will ensure that they continue to use it as they advance to larger projects.
The image component improves application performance with baked-in best practices
The main way we will improve application performance is through the integration of image-related best practices, such as the use of srcsets, preloads, and sized image assets. These practices are often not implemented, even on large Next.js applications, and can have major impacts on metrics such as LCP and CLS.
Reasons why image best practices currently aren’t followed include:
Developers aren’t aware of them.
Developers are aware of them, but implement them partially or incorrectly.
Developers are aware of them, but prioritize other development concerns. Following all best practices increases the amount of image-related code/markup in the codebase and imposes substantial infrastructure demands
I believe that a well-implemented image component should address all of the above obstacles. Developers will be made aware of the component due to prominent inclusion in the Next.js documentation, and the image component API will make component usage nearly as simple as using a standard img tag.
The image component precludes common performance-harming image mistakes
In analyzing many production Next.js applications, I’ve seen a lot of cases where application developers implement image-related functionality that is intended to provide a better user experience (such as image placeholders or lazy-loading), but they do so in a way that actually harms application performance. Sometimes this negative effect can be very substantial. The image component can help this problem in two ways:
By building in some commonly-desired functionality in a performant way, preventing developers from having to attempt to roll their own solution.
By integrating conformance measures that prominently warn developers when common mistakes are detected.
(Implementation Note: During the course of development, we shifted focus from warning-based conformance measures to preemptively stopping improper usage through type checking and runtime errors)
Feature Design
In this section, I’ll discuss the features of the image component that will allow it to accomplish the goals laid out in the section above.
Feature: Simple API
The image component will be able to be used much the same was as a standard
img
tag. The user will simply import the Image component into their page, much like the Link component is currently imported:jsThen they can use it in their code like so:
Feature: First-class status for CDNs
One of the most noticeable things about the Image component API discussed in the section above is that the src attribute takes only a relative path, not a full URL. This is both a convenience for developers (less mark-up in their files) and also an important part of how the Image component works.
As the component is rendered, a host is selected for the image. The host provides the absolute root of the URL (for instance, the URL of your particular CDN account, or the location of your self-hosted image server), which is combined with the relative path to get the actual image location.
For a description of how the host is selected, as well as how multiple hosts are handled, see the technical details selection at the end of the RFC.
Using this system, the Image Component is agnostic to whether the application is using a CDN or self-hosted images, and it’s easy to switch image providers later on, or to have different image providers for different environments.
Since most applications at scale use CDNs or dedicated image providers, this should allow the image component to provide performance benefits to all applications, including those with the largest reach--ensuring the best overall ecosystem impact.
(Implementation note: This feature changed slightly during development. Now, instead of designating a host (such as "cloudinary") per-image, you set a single application-level host in the next.config file. If you wish to use a different host for any image, you can provide a "loader" function as a property which defines how to generate sized urls for that image)
Feature: Automatic srcsets for images
One of the most important things you can do for image performance is to use the
srcset
attribute to specify different versions of the image to use at different viewport sizes. This prevents the application from loading unnecessarily large image files which waste network resources and, in the case of above-the-fold images, hurts the LCP metric.The main drawback of
srcset
attribute is that it requires quite a bit of additional markup and infrastructure support. The implementing developer has to make multiple versions of the image file available, and manually insert a link to each one.The Image component addresses this drawback by automatically generating a srcset for each image, using a customizable Image Loader. The Image Loader takes a set of parameters (such as relative path, breakpoint size, and image quality) and returns a complete URL for that resource.
The intent is that most applications will use a CDN, and the loader will take advantage of those CDN’s on-demand image sizing to generate the
srcset
URLs. For applications which self-host images, a separate loader can be used which integrates with a custom image processing build step.More information on loaders and self hosted images is available in the technical details section at the end of the RFC.
(Implementation note: In addition to strong support for CDNs, we expanded the support for dynamic sizing even without a CDN, through integration with the Image Optimizer)
Feature: Enforced Sizing
Another image best practice that is often ignored in the wild is that all images should have height and width attributes. These attributes give the browser the information necessary to save space for the image in the layout, even before the file transfer is completed. This prevents the layout from changing as images are downloaded, and thus strongly impacts the CLS metric.
Normal
img
tags do not require a size and width attribute, but the Image component will. For cases in which it’s impossible to know the size (or at least the size ratio) ahead of time, a special attribute will disable the sized requirement. In cases where the Image component is being used in a place where it’s likely to be above the fold, conformance can provide warning that use of the unsized flag will cause performance degradation.(Implementation note: The conformance check described above was not implemented, largely because of the difficulty of detecting probable below-the-fold images at build time. Additionally, there is another case where images can be unsized: images which use the
fill
layout style.Feature: Preconnect and Preloads
One of the main performance problems we see in Next.js applications is that they don’t include tags for images which appear “above the fold.” Without a preload, the network request for the image doesn’t begin until after the DOM is loaded, and the image transfer is given lower priority than the first party JavaScript.
In reality, we generally want the first few images to be downloaded with higher priority than the JavaScript, because much of the benefit of SSR or static pages is that the page can be presented, visually complete, to the user well before the application JavaScript has bootstrapped.
This has a very large impact on the LCP metric, which measures the time until the largest visible element on the page (which often includes the first large image on the page) is rendered. Properly preloading images can improve this metric on Next.js applications by 50% or more.
The image component will automatically add tags for any images which are given the priority attribute. Because this selection cannot be fully automatic and requires developer intervention, a conformance check will be added that throws a warning if a page includes elements, but none of them have the priority attribute.
The Image Component will also include a tag for any image hosts defined in the next.config.js file.
(Implementation Note: Through experimentation, I determined the tag to be unnecessary, as long as images are properly preloaded. So that isn't in the final implementation.)
Implementation Details
CDN Support
Support for various CDNs is provided through the use of a “Loader” architecture, which allows the application to define a template for rendering a set of universal data about the image into a URL for that asset.
For instance, a loader for the Imgix platform might take something like this:
And, in combination with host information from the config file, produce a URL for breakpoint width 800 that looks like
https://myApp.imgix.net/photos/foo.jpg?w=800%q=70
A Loader could easily be written for any CDN that supports those same image properties, and I expect we would ship multiple built-in loaders for common CDNs. Even if a CDN or image hosting solution doesn’t support every property provided, a Loader could be written that simply ignores the unsupported properties.
Support for self-hosted images
Though the Image component is designed with CDNs in mind, it will also work with locally hosted images. The application developer simply needs to add an image compression/resizing step into their build process, and write a custom loader that generates URLs pointing to the output paths used by that build process.
This shouldn’t be too difficult, as there are a variety of popular build tools for resizing images, and a custom loader can be as simple as a template string.
(Implementation note: This is actually much easier than described, thanks to the Image Optimizer, which provides exactly this functionality out-of-the-box for self-hosted images.)
Out-of-the-box image support for new developers
The above section discusses adding custom support for self-hosted images, but doesn’t cover the case of new developers who are trying Next.js out for the first time. We want those developers to get used to using the Image component (and getting the associated performance benefits), but obviously we can’t tell them to develop a custom image pipeline and image loader as part of the Getting Started guide.
A satisfactory solution to this problem will involve additional technology for processing and hosting images directly from the Next.js server itself. With a system for that in place, we could simply include a default Image loader that points back to an image proxy on the Next.js server, which would allow robust out-of-the-box image inclusion, without sacrificing the flexibility to use the Image component with whatever image hosting solution the application developer prefers.
That work is beyond the scope of this RFC, but I believe we will be able to coordinate development on that feature so that it’s available shortly after the release of the Image component.
Support for files from multiple sources
It’s not uncommon for an application to feature images served from multiple image hosts. The Image component will support this through an optional host attribute that lets the user specify from one of multiple hosts declared in the next.config.js file. The component will use both the host substring and the loader registered to go along with that host in constructing the URL.
If no host attribute is supplied, the default host and loader will be used.
(Implementation note: This changed somewhat. Instead of supporting multiple pre-configured hosts that you can select between with an attribute, the developer now gets one default host, and any additional hosts can be defined by passing a custom loader function to the individual image component. Commonly-used custom loaders can be managed by creating a custom image component that wraps in the custom loader. An example of that is included in the linked documentation.)
Support for one-off sources
There may be cases where the application wants to link to an externally hosted image without defining a loader for it. For these cases, we’ll need to provide access to a noOptimization attribute that tells the image component to use the URL exactly as provided and disables all loader-based features. As this will disable some of the performance benefits, conformance should warn if this usage is detected, particularly above-the-fold.
(Implementation note: The name of this attribute ended up being
unoptimized
.)What about the sizes srcset property?
Unlike the
srcset
urls, which can be automatically generated based on the Image Loader and a static set of page breakpoints, the sizes attribute cannot be automatically determined. The best solution available to us is to pass through a sizes attribute from the Image component, and use the Image component documentation and conformance to educate developers on the importance of including sizes information.What about background-image images?
We will recommend that people not use the background-image CSS property if it can be avoided. Most common uses of background-image (such as superimposing text over an image) can be implemented using a normal image, and performance is generally better (and definitely not worse) if developers do so. For cases that cannot reasonably be accomplished with a normal image (such as repeating background graphics), we can at least advise the developers to add the appropriate preload tags, and to in-line the CSS for above-the-fold images, for better performance.
(Implementation note: This use-case is primarily supported using the
fill
layout style.)No priority images warning and dismissal
Because preloads are a major performance benefit, we want to make sure that people are actually using the priority attribute, and we should therefore provide a build-time conformance warning when we discover that:
There are Image component images on a page, and
None of those images have the priority attribute.
Of course, it’s possible for there to actually be no priority images on a page, if there is only text or other non-image content above the fold. In that case, we need to provide a way to silence the warning. I propose to do this via a field in the image section of the next.config.js file.
Images subject to additional scrutiny (initial page load + early in doc)
Some images are more likely to be performance-sensitive than others. Some specific cases:
Any image that is not visible on initial page load (for instance, because it’s a descendent of a hidden element) is not performance-sensitive.
Any image that is behind many other images is unlikely to be performance sensitive. The 8th image on the page probably is not above the fold.
Conformance checks do not need to be as stringent for images that aren’t performance sensitive. For instance, the unsized attribute should cause a build-time warning, except for images which are unlikely to be above-the-fold. Unsized images are primarily a problem for layout stability (and the CLS metric), which only matters for above-the-fold elements.
(Implementation note: This feature, as well as the preceding one were not actually included with the initial image component loadout. Ideally these will eventually be addressed soon with a runtime conformance feature)
Image element attributes
*Height and width are required unless the unsized flag is present
(Implementation note: See a final list of all property names here. Notably, the 'unsized' property was removed.)
Development Plan
Image Component v0.5
The first phase of development will be to develop a minimum viable Image Component that provides some performance benefit, so that we can quickly begin receiving feedback on the API design choices. This version will include functionality and testing for the following features:
Basic Image component functionality with ability to include and style images on the page
The Loader architecture for image URL generation
host attribute
Automatic srcset generation with sizes passthrough from the component
Estimated development time: 1-2 weeks
Image Component v0.9
This release will include the rest of the features required for the Image Component to satisfy the design considerations described in this RFC. It will include functionality and testing for the following features:
Image preloads and preconnects with the priority attribute
The noOptimization attribute.
Conformance rules that warn on the following:
No image with priority attribute
Use of the noOptimization attribute on performance-critical images
Performance-critical images with the unsized attribute
Estimated development time: 1-2 weeks
Image Component v1
The Image component will be ready for widespread adoption and promotion when the associated work on an integrated Next.js image hosting technology is complete. Development on that feature should be tracked alongside development of the features in the Image component itself.
Beta Was this translation helpful? Give feedback.
All reactions