Open mmazzarolo opened 1 year ago
Yep, I'm experiencing the same issue when using placeholder="blur"
and plaiceholder for for base64Data
Same, I'm having this same issue. Have any of you found a work-around?
@focux A workaround is using the onLoad
function on the Image component.
You can have a state variable to keep track of whether or not the image has loaded and only add the blur props when the image hasn't finished loading, i.e.
const [imageLoaded, setImageLoaded] = React.useState<boolean>(false);
return (
<Image
src={image.url}
{...(blurDataURL && !imageLoaded && { placeholder: 'blur', blurDataURL })}
onLoad={() => {
setImageLoaded(true);
}}
/>
);
This bug only impacts next dev
with App Router.
When I try with next build && next start
, then the blur placeholder is removed as soon as the image is loaded.
The issue appears to be related to main-app.js
taking 350ms to load which is blocking all client side js like react state (not just next/image).
Nope, this happens when served from Vercel too and this doesn't work either, the onLoad
will not fire until the image 100% finishes loading.
See here, it's as if the gif was still loading frame by frame (hence why the first animation is so slow), so technically the image hasn't finished loading. But it is already being displayed (albeit frame by frame) at which point I don't want to see the placeholder. Second animation goes on full speed and the placeholder is no longer visible.
These don't work either, only onload
and onLoad
is printed to the console.
<Image
// onLoad={hidePlaceholder}
// onLoadStart={hidePlaceholder}
onLoad={() => console.debug('onLoad')}
onLoadStart={() => console.debug('onLoadStart')}
onLoadedData={() => console.debug('onLoadedData')}
onLoadedMetadata={() => console.debug('onLoadedMetadata')}
// ref={ref => ref && (ref.onload = hidePlaceholder)}
ref={ref => {
if (!ref) return
ref.onload = () => console.debug('onload')
ref.onloadstart = () => console.debug('onloadstart')
ref.onloadeddata = () => console.debug('onloadeddata')
ref.onloadedmetadata = () => console.debug('onloadedmetadata')
}}
/>
Alright, this works like a charm! Just use it in place of Next/Image. It has the same signature.
Before:
<Image
src={getStaticAssetURL('core.gif')}
placeholder={coreStaticDataURL}
/>
After:
<LoadingImage
src={getStaticAssetURL('core.gif')}
placeholder={coreStaticDataURL}
/>
/* eslint-disable jsx-a11y/alt-text */
import Image from 'next/image'
import { useReducer } from 'react'
/**
* This component is a drop-in replacement for next/image that shows a placeholder image while the image is loading.
*
* *GitHub Issue: Placeholder of next/image is still visible after the image is loaded*\
* https://github.com/vercel/next.js/issues/53329
*/
//@ts-ignore
export const LoadingImage: React.FC<LoadingImageProps> = ({ placeholder, ...props }) => {
//@ts-ignore
const [isLoading, stopLoading] = useReducer((_, ev) => (props.onLoad?.(ev), false), true)
// prettier-ignore
return (
<>
{isLoading && placeholder &&
<Image
{...props}
placeholder={undefined}
src={placeholder}
/>
}
<Image
{...props}
className={`${props.className} ${isLoading && 'absolute invisible'}`}
placeholder={undefined}
onLoad={stopLoading}
/>
</>
)
}
export type NextImageProps = Parameters<typeof Image>[0]
export interface LoadingImageProps extends NextImageProps {
placeholder: NextImageProps['placeholder']
}
You'll need to define also css (uses tailwind)
.invisible {
visibility: hidden;
}
.absolute{
position: absolute;
}
@ackvf Thank you!
I also get this issue in nextjs 14 and blur data did not have border radius from original photo .
the issue also exists in onLoad in iPhone it gets triggered too fast before image is 100% loaded, and my loading image does not appear
works fine in web and android
Verify canary release
Provide environment information
Which area(s) of Next.js are affected? (leave empty if unsure)
Image optimization (next/image, next/legacy/image)
Link to the code that reproduces this issue or a replay of the bug
https://codesandbox.io/p/sandbox/pensive-mccarthy-yfz9lg
To Reproduce
next/image
to load an image that has a transparent background.placeholder="blur"
on such image.Describe the Bug
The image/style generated by setting
placeholder="blur"
on anext/image
can still be seen (for some time) after the image has been loaded.Example from the attached Codesandbox:
You can see other people reporting and discussing this bug at https://github.com/vercel/next.js/issues/42140#issuecomment-1342533513 .
For reference, here's how a Gatsby image with blur setup looks like out-of-the box:
https://github.com/vercel/next.js/assets/9536354/3484be15-066e-4ad0-9eef-4fd7c0c238a0
Expected Behavior
The placeholder image/style should immediately disappear when the image is loaded. Or, the generated image placeholder should respect the transparency pixels of the used image.
Which browser are you using? (if relevant)
Chromium Engine Version 115.0.5790.114
,Safari Version 16.5.2 (18615.2.9.11.10)
How are you deploying your application? (if relevant)
No response
NEXT-1679