Caching over 1,000 images


#1

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?


#2

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.


#3

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;
};


#4

Hi, which hashing function is this?


#5

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

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

Hope this clarifies.


#6

The medium story below contains five things you ought to know about this topic: https://medium.com/@wcandillon/5-things-to-know-about-images-react-native-69be41d2a9ee