[avatar] Fallback flashes for cached images on SSR hydration
- Dominant language
- TypeScript
- Stars
- 10.9k
- Forks
- 543
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 101
Description
# Bug report
## Current behavior
`Avatar.Fallback` produces a visible flash during SSR hydration even when the image source is already in the browser cache.
`useImageLoadingStatus` has no synchronous cached-image fast-path. It always initializes as `'idle'` and the only path to `'loaded'` is the async `onload` callback. Since `useIsoLayoutEffect` is a no-op on the server, the fallback is baked into the server HTML with no Avatar `` at all. After hydration, the layout effect fires but never checks `image.complete`, which is already `true` synchronously for cached images.
https://github.com/mui/base-ui/blob/master/packages/react/src/avatar/image/useImageLoadingStatus.ts#L17

Left: base-ui Avatar shows red fallback. Right: plain `` with the same cached URL renders instantly.
Measurements with 4x CPU throttle on a minimal page (image shown above):
| Framework | Red fallback frames | Flash duration |
|-----------|:---:|:---:|
| TanStack Start | 14 | ~304ms |
| Next.js | 3 | ~52ms |
| Vite SPA (client-only) | 1 | ~16ms |
The client-side case is a single-frame flash but the SSR case is the real problem. The flash duration scales with hydration time and gets worse on slower devices or larger pages.
## Expected behavior
For cached images, `Avatar.Image` should render immediately without showing `Avatar.Fallback`. A plain `` with the same cached URL renders instantly on first paint.
## Reproducible example
Any `Avatar` with a cached `src` and a visible fallback during SSR hydration. Tested with both Next.js and TanStack Start.
## Base UI version
v1.3.0
## Which browser are you using?
Chrome, Firefox
## Which OS are you using?
Windows, MacOS, Linux
## Additional context
Radix Avatar handles this with an `image.complete` check in the `useState` initializer to skip the fallback on the first render for cached images: [radix-ui/primitives](https://github.com/radix-ui/primitives/blob/22473d16404bfd446305db5b6c9308aece99fdec/packages/react/avatar/src/avatar.tsx)
Happy to open a PR that addresses this.
Contributor guide
Assessment
This issue has not been assessed yet.