Please provide the following:
- SDK Version: 38
- Platforms(Android/iOS/web/all): Android
Tested with Android but I suppose this applies to iOS to some extent. I assume this is a long-running problem with React Native Image.
Several images take about 700ms to display, and 200ms for single image. This looks really ugly, now I really understand the purpose of fadeDuration option, even with a fade the app ends up in uncanny valley because this looks anything but native.
This is how this looks with Android Studio emulator, which is the worst case scenario for me because it’s sluggish on my side.
Given an array of image modules:
const imgs = [require('./img001.png), ...];
- Image modules provided as
Image
source (a snack):
<View style={styles.container}>
<View style={styles.grid}>
{imgs.map((img, i) => <Image style={styles.logo} source={img} fadeDuration={0} key={i} />)}
</View>
</View>
Several images appear with different delays (up to 1s):
- Preloaded
Asset
with uri asImage
source and delayed splashscreen (a snack):
const [ready, setReady] = React.useState(true);
React.useLayoutEffect(() => {
SplashScreen.preventAutoHideAsync()
.then(() => Promise.all(imgAssets.map(asset => asset.downloadAsync())))
.then(() => setReady(true))
.then(() => SplashScreen.hideAsync())
}, []);
return ready && (
<View style={styles.container}>
<View style={styles.grid}>
{imgAssets.map((imgAsset, i) => <Image style={styles.logo} source={{ uri: (imgAsset.localUri || imgAsset.uri) }} fadeDuration={0} key={i} />)}
</View>
</View>
);
All images appear with roughly the same delay (~700ms) after a splashscreen:
- A splashscreen is disabled after
Image
onLoadEnd (a snack):
const readyPromise = React.useMemo(() => {
let resolve;
const promise = new Promise(r => resolve = r);
promise.resolve = resolve;
return promise;
}, []);
const onLoadEnd = React.useMemo(() => {
let imgCount = imgs.length;
return () => {
if (!--imgCount) readyPromise.resolve();
};
}, [readyPromise]);
React.useLayoutEffect(() => {
SplashScreen.preventAutoHideAsync().catch(e => console.error(e))
.then(() => readyPromise)
.then(() => SplashScreen.hideAsync()).catch(e => console.error(e))
}, [readyPromise]);
return null || (
<View style={styles.container}>
<View style={styles.grid}>
{imgs.map((img, i) => <Image style={styles.logo} onLoadEnd={onLoadEnd} source={img} fadeDuration={0} key={i} />)}
</View>
</View>
);
Image assets don’t seem to affect loading time. All images appear with no delay but onLoadEnd introduces an excessive delay (>1s).
Notice that splash screen API is ignored in snacks for some reason, 2 and 3 need to be cloned to local project to reproduce how it really works.
I’m interested in displaying local images without a lag to not break a native experience but not sure what are my options.
Is 3 the only way in managed workflow? Is react-native-fast-image the way it’s done in bare workflow?
I’ve learned about oncoming expo-image from here. Can it really help?