Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

next image optimization significantly slower in next after 10.0.7 #23637

Closed
mjenzen opened this issue Apr 2, 2021 · 60 comments
Closed

next image optimization significantly slower in next after 10.0.7 #23637

mjenzen opened this issue Apr 2, 2021 · 60 comments
Assignees
Milestone

Comments

@mjenzen
Copy link

mjenzen commented Apr 2, 2021

What version of Next.js are you using?

10.1.3-canary-0

What version of Node.js are you using?

12.12

What browser are you using?

any

What operating system are you using?

linux server

How are you deploying your application?

next start

Describe the Bug

The latest canary releases seem to have fixed the image optimization memory consumption, however the initial image optimization is noticeably slower than the previous version (10.0.7) and can take seconds to populate images on the page. It seems to be exacerbated by loading more images in quick succession as well.

Expected Behavior

Images should load with minimal delay as seen in 10.0.7 to prevent degrading user experience

To Reproduce

Load a page with numerous next/image components and look for images popping in significantly after page load

@mjenzen mjenzen added the bug Issue was opened via the bug report template. label Apr 2, 2021
@karlhorky
Copy link
Contributor

karlhorky commented Apr 2, 2021

Below is some more context in the tweet from @lovell, the sharp maintainer. Benchmarks may not be completely optimized, but apparently the squoosh approach now in Next.js is up to 25x slower:

Benchmark: lovell/sharp#2643

Tweet: https://twitter.com/lovell/status/1376647760309587979

@JimmyGray
Copy link

I'm having the same issue. Some of our pages have 20+ images and the difference is huge. I've rolled back to 10.0.6 for now.

@henryStelle
Copy link

I've experienced the same problem, @JimmyGray.
As explained in #22253, sharp was removed to decrease bundle size and increase supported platforms. However, some of these issues have been partially addressed with the v0.28 release of sharp lovell/sharp#2604.

@amuttsch
Copy link

amuttsch commented Apr 8, 2021

We had to roll back as well. We have up to 40 images per page which takes up to a minute to process on my local machine. Due to business concerns we cannot cache images indefinitely and have to regenerate them each day. The current performance is not working on production for us if users have to wait dozens of seconds to see images. We also had to roll back to 10.0 for now.

Is it possible to revert back to sharp as they have addressed the compatibility issues or maybe using it with a feature flag? Thanks!

@kripod
Copy link
Contributor

kripod commented Apr 13, 2021

I would love to see bringing back sharp, potentially as an optional peer dependency. Although Squoosh is a fantastic project on its own, I think it should only be used as a fallback or an opt-in until the situation with ARM machines improves.

@addyosmani
Copy link

@amuttsch would it be possible to share a URL with examples of the kinds of images per page that are taking a long time to process locally? Speaking with the Squoosh team about the performance feedback on this thread and any repros would be helpful to look at :)

@NikhilVerma
Copy link

NikhilVerma commented Apr 19, 2021

We are also noticing similar issues:

  • Image sizes are larger for the same quality parameter, I believe Next.js should reduce the default image size from 75 to compensate. Otherwise the consumers will see their website sizes grow. Here is an example.
    • image1 this image comes from an older version of Next.js 56.4kb
    • image2 same image, same quality with the latest next.js version 63.4KB
  • The response times for first requests have increased tremendously, you can use the same images in the previous example and tweak the quality param to something new. I see at least 3x slowdown in my testing.
  • We use a lot of local images and Next.js caches them only for 60s with no way to override that value. So every 60s we have to face with a long load time for requested images along with a high CPU usage.

My recommendations

  1. Re-add sharp as a additional config/override/loader. I am not sure if we can get faster than a bare-metal native implementation, even if WASM is making great strides.
  2. Allow overriding the default seconds for cache

Our solution

For now to mitigate this we are adding an additional layer of caching on top of /_next/image in our NGINX instance. It's not ideal because we shouldn't be needing this layer but it helps with the 60s expiry of Next.js local assets.

Here is a sample config

http {
    proxy_cache_path /tmp/image_cache levels=1:2 keys_zone=image_cache:30m use_temp_path=off inactive=7d max_size=2G loader_files=100 loader_sleep=50 loader_threshold=200;
    proxy_cache_valid 604800s; # 7 days
    proxy_cache_lock on;
    proxy_cache_use_stale updating;
    proxy_buffer_size 16k;
    proxy_buffers 16 16k;
    proxy_buffering on;
    proxy_http_version 1.1;
    proxy_ignore_headers Vary;
    proxy_ignore_headers Expires;
    proxy_ignore_headers Set-Cookie;
    proxy_ignore_headers Cache-Control;

    server {
        # ... server params

        # NextJS Proxy for images
        # We need this because of https://github.com/vercel/next.js/issues/23637#issuecomment-822358192
        # Until it's improved we need to maintain our own copy of next/images
        location /_next/image {
            proxy_pass http://localhost:3001;

            # request_uri is important because images have GET params which define quality, url and size
            # $http_accept is important because it changes the response type of next/image
            proxy_cache_key "$request_uri$http_accept";

            proxy_cache image_cache;
        }
    }
}

@amuttsch
Copy link

@addyosmani Unfortunately, I'm not able to share images due to copyright and licensing concerns.

But to give you some metadata: our source images are around 500-1000kB in size and have a resolution around 1500x2300 pixel and they are sized down to a width of ~220px using q=75 and webp format. I hope this helps you :-)

@timcole
Copy link

timcole commented Apr 21, 2021

Just jumping in here to add my info on this. I recently switched to next 10.1.4-canary.10 to see if that solved the image memory leak but unfortunately our web servers were still using 1GB of ram each (we only use next/image for 5 images). Switching back to 10.0.6 we average around 30Mi.

Example Images:
https://constellation.spaceflight.live/falcon9.webp
https://constellation.spaceflight.live/SN11.webp
https://constellation.spaceflight.live/b/b1fd1f3a97183e4a8d04794c71b7fdaf.webp
https://constellation.spaceflight.live/b/cd23264325291a089910a28d70139647.webp
https://constellation.spaceflight.live/b/431a992c3171c39331a337f99533c3cc.webp

Code is public at https://github.com/spaceflight-live/comet

@fabb
Copy link
Contributor

fabb commented Apr 30, 2021

I'm seeing a response time increase of 12% after updating from 10.0.7 to 10.2.0 (and updating from webpack 4 to webpack 5). I'm not using the image optimization feature at all though. Could the issue still be related to this issue?

@fabb
Copy link
Contributor

fabb commented May 12, 2021

I created a separate issue: #25032

@avisra
Copy link

avisra commented May 13, 2021

I am also seeing significant slowdowns. This has me wanting to roll back to 10.0.7... but there have been so many other fixes since then. What's the status of this issue @timneutkens? Is there enough information to work on it - or is this ticket still blocked?

@mbretter
Copy link

mbretter commented May 19, 2021

I am also encountering problems, after upgrading from 10.0.5 to 10.2.0 node is constantly crashing with an out of memory error.
Rolling back to 10.0.5, everything is running fine.

@thomasgrivet
Copy link

Hello!

I am also having issue when using versions > 10.0.7, in order to upgrade I need to run my application in a container with more memory and even then the images load after 7 seconds or so, which is just not acceptable for our use-case.
When using Next 10.0.7 images takes about 2 seconds to get fully loaded when not cached.
I would love to use the new features such as router.isPreview and more, but I also know it can be hard to make the right decisions for everyone. I hope we will be able to decide the way our application handle the optimisation process in the near future.

@bravetheheat
Copy link

is there no progress on this?

@deadcoder0904
Copy link

deadcoder0904 commented Jun 1, 2021

What's the status of this issue?

There are so many issues opened regarding it.

The API is weird & leads to many styling issues. It's promoted heavily but has many issues. Ideally, it should be a drop-in replacement for <img /> tag. Probably should still be in beta. Next.js is so simple but the Image component feels really odd.

I only have 1 Unsplash image & even that takes ~30 seconds to load. The fun part? It's running on localhost.

Repro can be found here → https://github.com/deadcoder0904/better-code-blocks/

@jca41
Copy link

jca41 commented Jun 1, 2021

What's the status of this issue?

There are so many issues opened regarding it.

The API is weird & leads to many styling issues. It's promoted heavily but has many issues. Ideally, it should be a drop-in replacement for <img /> tag. Probably should still be in beta. Next.js is so simple but the Image component feels really odd.

I only have 1 Unsplash image & even that takes ~30 seconds to load. The fun part? It's running on localhost.

Repro can be found here → https://github.com/deadcoder0904/better-code-blocks/

30 second seems too high, have you tried setting priority true on the <Img />?
Is it showing above the fold or not?

The performance decrease i'm seeing is around ~20% or 30%

@DPangerl
Copy link

DPangerl commented Jun 1, 2021

I think the priority prop does not affect performance of the image processor. It simply deactivates lazy loading.
As long as the image is not visible it should not be loaded at all.

I have about 6 images on my website. With 10.0.7 the images don't need more than 1 sec to load. With 10.2.0 every single image needs about 9 sec to load (priority or not).

In combination with the 60 sec life time of the cache this is way beyond acceptable.
Why is the caching duration this short anyways?

I'm a bit surprised, this issue does not gain more attention as loading images is a common part of every website.

However… in my opinion, sticking with 10.0.7 is the best option for now.

@olikami
Copy link

olikami commented Jun 1, 2021

In my testing, this is not a problem in the image component, but rather of the image resizing server that is used if there is no other loader setup.

My current workaround is that i have written a custom image loader as an API route, thatuses Sharp again... (This also allows me to control the caching by myself)

@karlhorky
Copy link
Contributor

karlhorky commented Jun 1, 2021

My current workaround is that i have written a custom image loader as an API route, thatuses Sharp again... (This also allows me to control the caching by myself)

Yeah, seems like that the Next.js team (cc @shuding) should consider adding back sharp as an option - maybe even as the default option.

@rauchg mentioned this as an option for a loader here: https://twitter.com/rauchg/status/1376654853963845638

I'm guessing the performance of the current squoosh-based option will not improve without some serious work (if there were low-hanging fruit, seems like this would have been done already).

@kristianstroka
Copy link

In my testing, this is not a problem in the image component, but rather of the image resizing server that is used if there is no other loader setup.

My current workaround is that i have written a custom image loader as an API route, thatuses Sharp again... (This also allows me to control the caching by myself)

Can you get us example how to use Sharp as custom loader? I tried to do that, but without success, not sure what I'm doing wrong ... that is sad, that next developers are not focusing on this issue, which is really big and a lot of people are complaying about that ... :(

@jca41
Copy link

jca41 commented Jun 1, 2021

I think the priority prop does not affect performance of the image processor. It simply deactivates lazy loading.
As long as the image is not visible it should not be loaded at all.

I have about 6 images on my website. With 10.0.7 the images don't need more than 1 sec to load. With 10.2.0 every single image needs about 9 sec to load (priority or not).

In combination with the 60 sec life time of the cache this is way beyond acceptable.
Why is the caching duration this short anyways?

I'm a bit surprised, this issue does not gain more attention as loading images is a common part of every website.

However… in my opinion, sticking with 10.0.7 is the best option for now.

Yeah true, was just considering that in his case with a 30s load time on localhost maybe the issue could be somewhere else.

This is the kind of performance im getting currently. I would have to downgrade next and mesure the perf decrease to have exact numbers, but it does feel a bit slower

  • Examples of 3 images loaded with Image

Screenshot 2021-06-01 at 09 51 07

  • The raw image loaded on a new tab

Screenshot 2021-06-01 at 09 51 25

@olikami
Copy link

olikami commented Jun 1, 2021

If anyone else wants to build their own image resizer I dropped our code in a gist (we only use this internally or for noncritical stuff): https://gist.github.com/olikami/236e3c57ca73d145984ec6c127416340

Please note that it isn't very good, the code is potentially buggy, and you'll use it at your own risk. In production, you should probably use something like thumbor or Cloudimage if SaaS is more your style.

@deadcoder0904
Copy link

30 second seems too high, have you tried setting priority true on the <Img />?

@jca41 Yes, I tried priority={true}, loading="eager", & even quality={60} to make it work but it's too damn slow. I know ~30 seconds is high but I did see twice or thrice in the Chrome Extension, the request gets fulfilled around ~30000-40000ms.

I have also provided the repro so you can check for yourself :)

Initially, I thought something was wrong with my code but img tag works fine.

@deadcoder0904
Copy link

@jca41 Whoops, it's ~8 seconds. I was checking the thing above it but your screenshot pointed me to look below. It's a 3.9MB image locally & image optimization makes it 73.1kB.

But yeah, still noticeable to see the difference. The props mentioned above don't make any difference at all.

unsplash-image

@jca41
Copy link

jca41 commented Jun 28, 2021

Did not experience any noticeable improvements with v11 (deployed on Vercel).

@Punkte
Copy link

Punkte commented Jun 28, 2021

Experiencing this as well, it's quite an annoying problem for the UX and the SEO ranking.
In the meantime you can improve the user experience by using the placeholder API.. 😕

@royjosefsson
Copy link

I'm experiencing the same issue. But for me, it's not the upgrading of next that is causing the issue, it's actually some peer dependencies. Look at my printscreen. As soon as i fix these 10 minor error, image becomes slow.
https://drive.google.com/file/d/1b20IsW3aaZ9WYJW_sK9KkfMYFDQEn2mH/view?usp=sharing

@valstu
Copy link

valstu commented Jul 3, 2021

@royjosefsson link doesn't work

@royjosefsson
Copy link

royjosefsson commented Jul 3, 2021

Sorry.
https://drive.google.com/file/d/1b20IsW3aaZ9WYJW_sK9KkfMYFDQEn2mH/view?usp=sharing

@valstu

@Tralgar
Copy link

Tralgar commented Jul 7, 2021

Will it be fixed soon plz ?
The first generation of a size seems really too long. Downgrade to 10.0.6 seems too work for me but now I'm missing features...

@DSamuylov
Copy link

After testing if for a while, I have an impression that even with the version 10.0.7 images are loaded quite slow. It still takes a few sec. It definitely faster, then with the latest version of next.js, but it is way slower than images embedded with img. Is there a chance that with an upcoming fix the images would be loaded faster than with the version 10.0.7? Otherwise, I am really considering to avoid using Image from next.js at all and rely only on img.

@goguda
Copy link
Contributor

goguda commented Jul 7, 2021

After testing if for a while, I have an impression that even with the version 10.0.7 images are loaded quite slow. It still takes a few sec. It definitely faster, then with the latest version of next.js, but it is way slower than images embedded with img. Is there a chance that with an upcoming fix the images would be loaded faster than with the version 10.0.7? Otherwise, I am really considering to avoid using Image from next.js at all and rely only on img.

Well of course it’s going to be slower than img by a bit, it’s optimizing on the fly before it serves the image and that takes a bit of time. However, the amount of time we’ve seen with more recent versions is just too long to be useable.

@DSamuylov
Copy link

@goguda yes, I understand that, but it take so long even in the older version (10.0.7) before the amount of time was increased. Of course you need to precompute images of different size and it takes time.

However, why is the cache so short lived? From what I remember it is only 60 seconds and then the images are recomputed again on a new request.

Would it make sense to add an option to increase the cache time or even save resized images on disk during the build time (if there are only a few images on the website and the space is not a concern)?

Or should it be handled elsewhere, for example by configuring cache in nginx?

@gu-stav
Copy link

gu-stav commented Jul 8, 2021

@DSamuylov Regarding the cache time: there is work going on to improve the situation:

In addition it was mentioned several times, that the next.js team is working (or at least planning to work) on a stale-while-revalidate solution for images already.

There is another issue, with proposed solutions and discussion around that topic:

@josegoval
Copy link

Is there any news about this? Any solutions?

@atcastle
Copy link
Collaborator

atcastle commented Jul 9, 2021

I've just posted an RFC (#27055) and have started development on a solution to this problem. The new feature will allow Next to use sharp for image optimization, if sharp is installed installed on the server (via yarn add sharp or installed globally). This should substantially improve image optimization performance, without increasing install size for people who don't need sharp.

@styfle styfle assigned atcastle and unassigned ijjk Jul 21, 2021
@WillSquire
Copy link

WillSquire commented Jul 23, 2021

Is there a release date for this opt-in method?

Been waiting months for a fix with the hope it will get released soon and checking in (as it's a fairly big issue), but the bounce rate is so high from slow loading that I may need to remove the Image component. Would be nice to have an ETA to know if it's worth it or not? Unfortunately the site was built after the update so rolling back wasn't really an option. Putting up NGINX proxy caching hasn't really helped as it's a low volume site that gets updated fairly frequently.

@karlhorky
Copy link
Contributor

karlhorky commented Jul 23, 2021

Posted this over on the discussion thread too:

Looks like @atcastle has opened a PR that was merged at #27346 🎉🎉 (already released in 11.0.2-canary.20)

As for non-canary versions, may be out in 11.0.2! 🚀

@anicolaides
Copy link

This has been fixed in 11.0.2-canary.20.

Simply, install the sharp package and it will automagically switch over to using sharp for image optimization.

@ijjk
Copy link
Member

ijjk commented Jul 23, 2021

The above comment is correct so I'm gonna close this as performance should be the same as before when sharp is installed

@fuzunspm
Copy link

fuzunspm commented Dec 17, 2021

[email protected] and [email protected] I'm having the same issue. img tag loads image almost instantly but Image takes about 7-8 seconds while making all cpu cores at 100%

@Me-UserName
Copy link

[email protected] and [email protected] I'm having the same issue.

@lednhatkhanh

This comment has been minimized.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests