[Expo-image] Is it possible to load local images without a FOUC?

No matter what I do expo-image is initially blank while loading local images. Seems like no caching is going on even with cachePolicy=“memory-disk” and loading the same image when going back and forth between screens. I’ve tried using Image.prefetch on the local image URIs which worked for fast-image but not expo-image. Am I missing something?

I’m having the same problem. This was supposed to be an alternative to FastImage but it doesn’t seem to be working.

I gave up on expo image and fast image. Only way I could get it to load instantly on Android was by rolling my own preload system using expo-file-system and encoding images as base64.

Hey, can you explain this solution? I’d love to implement it.

Something like:

  // Preload images from file system as base64 strings
  const filteredImages = images.filter(isNotNullOrUndefined);
  const imagePromise = Asset.loadAsync(filteredImages).then((assets) => {
    const promises = assets
      .map(({ localUri }, index) => {
        return localUri ? { localUri, index } : null;
      })
      .filter(isTruthy)
      .map(async ({ localUri, index }) => {
        const base64 = await readAsStringAsync(localUri, { encoding: 'base64' });

        preloadedBase64Map[filteredImages[index]] = { uri: `data:image/jpg;base64,${base64}` };
      });

    return allSettled(promises);
  });

And:

/**
 * Wrapper for the React Native Image component that will use the preloaded uri source if possible.
 * Otherwise defaults to original require based source which will load asynchronously.
 * If images are failing to load on Android, try setting resizeMethod="resize".
 * @param props Any props passable to React Native's Image component.
 * @returns Image component with modified props.
 */
export function PreloadedImage(props: ImageProps) {
  return <Image fadeDuration={0} {...props} source={getPreloadedSource(props.source)} />;
}

/**
 * Gets the URI-based source if image has been preloaded.
 * URI-based sources don't have a flash of unloaded content initially.
 * @param requireSource E.g. require('src/foobar.png')
 * @returns URI-based source, otherwise fallback is the original require-based source.
 */
export function getPreloadedSource(requireSource: any) {
  return preloadedBase64Map[requireSource] || requireSource;
}

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.