RFC: Image Optimization #17141
Replies: 17 comments 12 replies
-
Finally 🚀. Can’t wait to get that 100 lighthouse performance scores once again 😋 |
Beta Was this translation helpful? Give feedback.
-
Wow, this is fantastic!!! |
Beta Was this translation helpful? Give feedback.
-
Would it also allow overriding the image format with a query parameter? There will be scenarios where I’d want to explicitly specify a format — for example, using PNGs when the image has more lines and using JPGs when the image is more photo-realistic. Of course AVIF does both of these kinds really well, but while we wait for more widespread browser support, the ability to specify the image format would be nice. |
Beta Was this translation helpful? Give feedback.
-
I assume ^this non-goal also covers generating image placeholders? (blurred images, used colours, etc.) #16832 also doesn't include the use of placeholders so it looks like it isn't a goal for either RFC, but they are one of the best features of |
Beta Was this translation helpful? Give feedback.
-
Is there any consideration for signing image URLs like Thumbor to prevent URL tampering? Even though you can configure the allowed image domains, this proposal would leave the image endpoint open to denial of service attacks. From the Thumbor documentation:
|
Beta Was this translation helpful? Give feedback.
-
Does this mean that for the first time a request is made an image is generated, and then every subsequent requests will serve the created image? Is it basically a smart image cdn? I guess it will be cleaned between builds though? |
Beta Was this translation helpful? Give feedback.
-
I'd like to propose a few things to consider adding into this RFC which would be very useful.
We wrote a similar solution using vips/sharp (not maintained at the moment) to be able to replace our SaaS for image optimization and manipulation, it explains a bit more what I ment by signed urls and more params to control the image - in case that would be helpful :-) |
Beta Was this translation helpful? Give feedback.
-
How would this work for generated static sites? |
Beta Was this translation helpful? Give feedback.
-
I think optimizing at build time its valid in a lot of use cases and it does not require to have serverless support to handle the requests, I do agree that it should have some sort way to only transform images once and skip for subsequent builds. Maybe add a new RFC for this? It is one of the most used features in some frameworks. |
Beta Was this translation helpful? Give feedback.
-
This is a great RFC, I am doing so already with Sharp, Vercel and NextJS. It works well, and Vercel gives good Cache Control.
Some truly unique remote URLs will probably not change and can be cached after they are resized. Others like Deploys cannot be relied upon to clear the cache either as this is online image processing.
Since this is server side fetching credentials would be required for the server to access non public assets. This prevents DDoS and therefore requires no next support for masked URLs. This may mean a user must supply a function that can fetch the image, it is not available over HTTP, or is only available securely over HTTP with environment variables. Would this be supported? Thanks 👍 |
Beta Was this translation helpful? Give feedback.
-
What would be the HTML output of such component and how would responsive imagery be achieved? Sometimes you want to serve images of with |
Beta Was this translation helpful? Give feedback.
-
What about DDOS? For example somebody makes thousands request with random query on |
Beta Was this translation helpful? Give feedback.
-
I wonder if image optimization is going to support rewrites? This could be helpful for adaptation and incrementally adopting Next.js. |
Beta Was this translation helpful? Give feedback.
-
The dream come true in v10. |
Beta Was this translation helpful? Give feedback.
-
Would love to see alternative storage options. Right now I'm assuming images get stored on disk, but with a large enough quantity of images we might eat up all the available storage on whatever server we are using. It also means we will be discarding these image caches if using Blue/Green deployments. If we could select an S3 bucket, for example, to store images we could mitigate this storage problem |
Beta Was this translation helpful? Give feedback.
-
Is Fallback optimize image to original format available at the moment? |
Beta Was this translation helpful? Give feedback.
-
Goals
npm install next
timeNon-Goals
next export
— The goals of the RFC and it's particular characteristics of on-demand optimizing over optimizing at build time which causes build time slowdownsBackground
#16832 is introducing the Image component that allows for a bunch of optimizations to be handled like lazy-loading and
srcset
generation. In order to fully leverage all optimizations you'd need to use specific image hosting services, that's not as ideal as having this built-in to Next.js itself so this proposal aims to cover building in a solution for optimizing images.Proposal
The image optimization will seamlessly integrate with
next/image
(#16832). In order to do so, Next.js will expose an endpoint similar to what image optimization services have.This endpoint will be under
/_next/image
and take a couple query parameters:url
the url of the image, this could be an absolute url or relative pathw
the width of the imageq
the output quality of the imageThe endpoint will automatically serve the best format (e.g.
webp
oravif
) based on if the browser supports it through theAccept
header. E.g. Google Chrome provides the following values:Example:
/_next/image?url=/logo.png&w=100&h=100&q=70
Will serve the/logo.png
as100x100
with70
quality.Note that you'd generally not construct the url in this way as you'd be using the
next/image
component shown in #16832To avoid abuse the user has to provide a list of supported image widths to avoid enumeration attacks:
Support for external images
Images on a web page are generally a blend of local images as part of the project and external images that come from an external data source. The image optimization will support both local images and external images.
In case of external images you'll need to add the domains (or domain pattern) to an allow list. This is to ensure that malicious users can't hijack the image optimization for their own use:
Install Time
The
npm install
time of Next.js is important as every new application being created, every CI build and development install would be slowed down by installing large dependencies. Image optimization libraries are notoriously large and depend on native dependencies. For examplesharp
which is being used in some frameworks has an install size of28MB
(source). For comparison thenext
package right now has an install size of50MB
of which the majority iswebpack
(source).When looking at https://squoosh.app/ we (@Timer and me) noticed that it ships WebAssembly files for the image optimization. Furthermore these files are really small (a couple hundred kB) compared to the existing image optimization libraries on npm and do not have native dependencies. Seemingly these files are a great candidate to solve the install time issue. They're located here: https://github.com/GoogleChromeLabs/squoosh/tree/dev/codecs
Upon further investigation we found that @cyrilwanner has ported these codes to npm libraries in this repository: https://github.com/cyrilwanner/wasm-codecs potentially we can use/reuse parts of this. The ideal outcome would probably be having these files published to npm from the squoosh repository so they're always up to date.
Upon even further investigation with help from @cyrilwanner who did a performance comparison of the webassembly version against
sharp
. The Sharp version is significantly faster (see results linked below)Cyril's comparison of image solutions
Performance comparison
Hardware
Tests run on a MacBook Pro 2018, with an 2.6 GHz 6-Core Intel Core i7 and 16 GB 2400 MHz DDR4 RAM.
JPEG
Tiny image (6.3KB)
Small image (166.0KB)
Medium image (603.8KB)
Large image (2211.2KB)
PNG
Tiny image (17.0KB)
Small image (139.4KB)
Medium image (538.7KB)
Large image (1949.6KB)
Currently the install size of
sharp
is mostly affected bylibvips
(around 20MB) coming from thelibvips
binary.libvips
recently announced a webassembly version that is around 5MB to install, however it has relatively similar results to what @cyril Wanner showed. It also currently depends on experimental Node.js / v8 features making it not feasible for adoption at this point in time.Overall having looked into all these options it seems that eventually using
libvips
with webassembly will be the way to go in the future (whether or not it will be an optional dependency will be decided then).However, for the time being we can make
sharp
an optional dependency if users want to leverage the image optimization and we'll make it work automatically aftersharp
is installed. This is very similar to how we tell people to installtypescript
which is 54MB (source).Beta Was this translation helpful? Give feedback.
All reactions