React Native FastImage or Image Component Showing White Flash Before Loading
Quick answer
A brief white flash before an image loads is a rendering/layout timing issue, not a networking problem — the image container renders and takes up its layout...
A brief white flash before an image loads is a rendering/layout timing issue, not a networking problem — the image container renders and takes up its layout space before the actual image content is ready to display, and without an explicit background color or placeholder, that empty space defaults to showing through as plain white (or whatever the underlying view's default background happens to be).
The Problem
Images in a list or screen briefly flash white (or show a plain empty space) before the actual image content appears, creating a visually jarring effect, particularly noticeable when scrolling through a list of images loading progressively.
Why It Happens
An Image or FastImage component reserves its layout space (based on its configured width/height) as soon as it's rendered, but the actual image content takes additional time to load — whether from the network, from disk cache, or even from bundled assets in some cases. During this gap between layout reservation and content actually being ready to display, the component shows nothing, and without any explicit styling addressing this empty state, the underlying default background (often white, or the parent view's own background color) shows through, creating the flash effect as the image finally pops in on top of it.
The Fix
Set an explicit background color on the image component itself, matching your app's design (a neutral gray, or a color matching your app's general theme), so the "empty, not yet loaded" state looks like an intentional placeholder rather than a jarring, unstyled flash:
<Image
source={{ uri: imageUrl }}
style={{ width: 200, height: 200, backgroundColor: '#e5e5e5' }}
/>
This single change alone often meaningfully improves the perceived experience, since a neutral gray placeholder reads as an intentional loading state rather than a visual glitch, even without any more elaborate loading indicator.
For a smoother, animated transition specifically avoiding an abrupt pop-in once the image does load, fade the image in using opacity animation once loading completes:
const [loaded, setLoaded] = useState(false);
<Animated.Image
source={{ uri: imageUrl }}
onLoad={() => setLoaded(true)}
style={{
width: 200,
height: 200,
backgroundColor: '#e5e5e5',
opacity: loaded ? 1 : 0,
}}
/>
For an even smoother visual transition rather than an instant opacity toggle, animate the opacity change explicitly using React Native's Animated API:
const opacity = useRef(new Animated.Value(0)).current;
const handleLoad = () => {
Animated.timing(opacity, { toValue: 1, duration: 300, useNativeDriver: true }).start();
};
<Animated.Image
source={{ uri: imageUrl }}
onLoad={handleLoad}
style={{ width: 200, height: 200, backgroundColor: '#e5e5e5', opacity }}
/>
If you're using FastImage specifically (generally recommended over the built-in Image component for better caching and performance, particularly with lists of many images), it supports a similar priority and caching configuration that can also help reduce perceived flash frequency by more aggressively caching previously loaded images, avoiding a repeated loading flash for images the user has already seen once:
import FastImage from 'react-native-fast-image';
<FastImage
source={{ uri: imageUrl, priority: FastImage.priority.normal }}
style={{ width: 200, height: 200, backgroundColor: '#e5e5e5' }}
resizeMode={FastImage.resizeMode.cover}
/>
For a genuine, more polished placeholder experience beyond a plain background color, consider a low-resolution blurred placeholder image (a common pattern sometimes called "blur-up" loading) shown immediately while the full-resolution image loads in behind it — this requires generating and storing a small placeholder version of each image alongside the full version, more implementation effort than a plain background color, but provides a noticeably more polished perceived-loading experience for image-heavy interfaces where this extra effort is worthwhile.
Still Not Working?
If the flash persists even with a background color and fade-in configured, check whether the flash is actually happening at the screen/navigation transition level rather than specifically at the individual image component level — a screen transition that briefly shows a blank white background before your actual screen content (including its images) renders is a related but architecturally distinct issue, requiring a fix at the navigation/screen transition configuration level (like setting an appropriate background color on the navigator itself) rather than anything specific to how individual image components are configured.