Caching over 1,000 images

I have over a thousand images in my app. It takes longer than 5 minutes to cache all of them on first load. If I opt out of caching, they’re slow to appear in the image tag. How can I make this process faster?

At the moment you can encode your images as base64 data strings. In the next few months we plan to build support for bundling your image assets into your standalone app.

In the meantime you could also define some images which are necessary to cache for your first render and fetch those during AppLoading (they’ll probably be cached for subsequent loads anyways) and then asynchronously begin caching other assets in the background while the user is interacting with the initial screen.

I just would like to share solution on to cache image. Hope this helps the next guy.

import React from 'react';
import { Image } from 'react-native';
import { FileSystem } from 'expo';

import { hashOf } from '../../utils/';


class SmartImage extends React.PureComponent {
  state = { source: this.props.source };

  componentDidMount() {
    this.mounted = true;
    if (typeof this.props.source === 'number') {
      return;
    }

    const remoteUri = this.props.source.uri;
    const fileUri = FileSystem.documentDirectory + hashOf(remoteUri) + '.jpg';
    FileSystem.getInfoAsync(fileUri)
      .then(({ exists, uri }) => {
        if (exists) {
            this.loadCacheImage(uri);
        } else {
          FileSystem.downloadAsync(remoteUri, fileUri)
          .catch(e => console.log(e));
        }
      }
    );
  }

  componentWillUnmount() {
    this.mounted = false;
  }

  loadCacheImage = (uri) => {
    if (this.mounted) {
      this.setState({ source: { uri } });
    }
  }

  render() {
    const newProps = { ...this.props, source: this.state.source };
    return (
      <Image {...newProps} />
    );
  }
}

export default SmartImage;

Here’s the hash function that use to convert URL to a filename.

export const hashOf = (str) => {
    /*jshint bitwise:false */
    let i;
    let l;
    let hval = 0x811c9dc5;
    // let hval = (seed === undefined) ? 0x811c9dc5 : seed;

    const asString = true;

    for (i = 0, l = str.length; i < l; i++) {
        hval ^= str.charCodeAt(i);
        hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
    }
    if (asString) {
        // Convert to 8 digit hex string
        return ('0000000' + (hval >>> 0).toString(16)).substr(-8);
    }
    return hval >>> 0;
};

1 Like

Hi, which hashing function is this?

The hash function converts the URL into the hash number. For example:

http://example.com/image.jpg ==> abcd1234

Hope this clarifies.

The medium story below contains five things you ought to know about this topic: 5 Things to know about Images in React Native | by William Candillon | Medium

1 Like

How about using a component like FastImage ? I started using it just now and it litteraly changed everything. Add fast images and the blurring with base64 described by other people and I believe your problem would be solved.