You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: x64
Version: Darwin Kernel Version 21.6.0: Wed Aug 10 14:25:27 PDT 2022; root:xnu-8020.141.5~2/RELEASE_X86_64
Binaries:
Node: 16.16.0
npm: 8.11.0
Yarn: 1.22.18
pnpm: N/A
Relevant packages:
next: 12.2.5
eslint-config-next: 12.2.3
react: 18.2.0
react-dom: 18.2.0
warn - Latest canary version not detected, detected: "12.2.5", newest: "12.2.6-canary.6".
Please try the latest canary version (`npm install next@canary`) to confirm the issue still exists before creating a new issue.
Read more - https://nextjs.org/docs/messages/opening-an-issue
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
I have a page with hundreds of table cells and an image in each of those table cells (so my page contains hundreds of images). When an image is selected, a sidebar opens with details, and I replace the URL in the location bar using useRouter.
I've been having performance issues when selecting an image — the interaction would take 500ms+, so I've been going through my code to optimize everything.
I'm able to optimize everything via memoization except for the next/image component (I'm actually using next/future/image but I've checked with both).
When I replace/push a new query string using useRouter, the whole tree rerenders. This is fine for most of my components because of my memoization. However, every Image component always rerenders (according to the React dev tools because of a context change). I've tried to wrap the Image component with useMemo but no matter what I try, the Image component rerenders.
If I replace the Next Image component with a plain img, my memoization is perfect and those img components do not rerender. However, I really want to use the Image component because of all the features it offers.
Is there any way to stop the Image component rerendering when the context/router changes? Am I missing something?
If there isn't a way currently, perhaps this is a bug? It seems quite important to have control over when the component rerenders when using useRouter or making a change in the context.
Update
Looking at the ranked chart in the profiler, it seems it may be ImageConfigContext and/or RouterContext causing these rerenders. As mentioned above, I can stop my own components rerendering by memoizing them, but that doesn't seem possible with the Next Image component.
useRouter returns the routing state, so obviously it has to update when a routing action happens. But the push etc methods should not similarly need to update.
The problem is that both the state and the methods for changing it are lumped into the same React context.
This issue has been automatically marked as stale due to two years of inactivity. It will be closed in 7 days unless there’s further input. If you believe this issue is still relevant, please leave a comment or provide updated details. Thank you.
Verify canary release
Provide environment information
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
I have a page with hundreds of table cells and an image in each of those table cells (so my page contains hundreds of images). When an image is selected, a sidebar opens with details, and I replace the URL in the location bar using
useRouter
.I've been having performance issues when selecting an image — the interaction would take 500ms+, so I've been going through my code to optimize everything.
I'm able to optimize everything via memoization except for the
next/image
component (I'm actually usingnext/future/image
but I've checked with both).When I replace/push a new query string using
useRouter
, the whole tree rerenders. This is fine for most of my components because of my memoization. However, everyImage
component always rerenders (according to the React dev tools because of a context change). I've tried to wrap theImage
component withuseMemo
but no matter what I try, theImage
component rerenders.If I replace the Next
Image
component with a plainimg
, my memoization is perfect and thoseimg
components do not rerender. However, I really want to use theImage
component because of all the features it offers.Is there any way to stop the
Image
component rerendering when the context/router changes? Am I missing something?If there isn't a way currently, perhaps this is a bug? It seems quite important to have control over when the component rerenders when using
useRouter
or making a change in the context.Update
Looking at the ranked chart in the profiler, it seems it may be
ImageConfigContext
and/orRouterContext
causing these rerenders. As mentioned above, I can stop my own components rerendering by memoizing them, but that doesn't seem possible with the NextImage
component.I have also tried wrapping the
Image
element inuseMemo
like below but it still rerenders due to a context change.Expected Behavior
The Next
Image
component should provide a way to prevent rerender during a context change (likeuseRouter
changing).Link to reproduction
https://codesandbox.io/s/gifted-hermann-ygwj5u?file=/components/MyTile.tsx
To Reproduce
Using the regular Next
Image
component (non-memoized) (line 12 ofMyTile.tsx
), the render takes 547ms:Using the
memoedImage
component (line 13 ofMyTile.tsx
), the render takes 684ms:Using the native
img
component (line 14 ofMyTile.tsx
), the render takes 43ms (~12× faster):The text was updated successfully, but these errors were encountered: