Asset download mechanics may need more clarifications

I am confused about the mechanics of Expo and React-Native, how they download the assets. I searched the documentation asset preloading and caching but still I don’t have the clear view.

The info that I know is, once you build your code, expo prepares a bundle which contains both the javascript (compiled code) and the assets altogether.

And during a debug session, that bundle - as a whole - is first downloaded by the expo client and then the app is started. Which means all the assets that are "import"ed in the code should be in place once the application is started.

On the other hand this is completely opposite when I run the following atomic test code. It takes time to load those assets as if they are “lazy loaded”.

So my question is; is that behaviour development mode related or will it still take time to download images in the production mode?

  • If production mode will behave the same then where will it download the assets from?
  • If production mode is different than the development mode, why development mode is arranged to behave differently?
import * as React from 'react';
import { Text, View, StyleSheet, Image, Button } from 'react-native';
import Test0Img from './assets/test0.gif';
import Test1Img from './assets/test1.gif';

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      imageIndex: 0,
    };
  }

  render() {
    return (
      <View style={styles.container}>
        <Text></Text>
        <Text></Text>
        <Button
          onPress={() => {
            let l_newImageIndex = (this.state.imageIndex + 1) % 2;
            this.setState({ imageIndex: l_newImageIndex });
          }}
          title="Click to Change Image"
        />
        <Image
          source={this.state.imageIndex === 1 ? Test0Img : Test1Img}
          style={{
            width: '100%',
            height: '100%',
            resizeMode: 'contain',
          }}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
});

Code can be seen in this snack: https://snack.expo.io/@mehmetkaplan/assetdownloadtest

If you run this code in your mobile, most probably you’ll observe that the animated gif is not changed easily. But if you run it through web it changes quicker.

=====================
Originally searched for some help here but could not get any answer.

Hey @mehmetkaplan,

During development in the Expo client, the images will downloaded from your local environment. This will take longer due to the all the extra processes that run during Development Mode such as validation checks, remote debugging, hot reloading if enabled, etc. You can read more about this here: https://docs.expo.io/versions/v34.0.0/workflow/development-mode/

When running a published project within the Expo Client, it will fetch your assets from the CDN (CloudFront) in which case you’ll want to make use of the AppLoading module to pre-fetch the assets and only hide the splash screen after all assets have been loaded into memory.

When building a standalone application, you have the option to bundle your assets into the binary (which most should use unless they have an abnormal amount of assets or assets with heavy file sizes) that will result in the assets being loaded into memory much faster since they will be fetched from the local disk rather than making a network request to the CDN.

I hope that answers your question, if not let me know and I’ll try to provide further clarification.

Cheers,
Adam

This is perfectly clear. Thank you very much.

This is a great architecture, all the three scenarios - development, published within expo client and standalone - are exactly as expected.

I liked Expo once more! :slight_smile: