How to Lazy Load JSON

If you’ve ever wondered how to lazy load JSON (useful if you have large JSON files), here’s a quick guide on how to do so:

  1. Give your JSON file a custom extension (we’ll use the extension .lazy then create metro.config.js and add your custom extension to the assetExts:
const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig();

  return {
    resolver: {
      assetExts: [...assetExts, 'lazy'],
    }
  };
})();
  1. Configure app.json to use your metro config by adding the snippet below
"packagerOpts": {
      "config": "./metro.config.js"
 }
  1. Use the expo-asset and expo-file-system module’s to ensure the asset is downloaded, read to a string and parsed
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Asset } from 'expo-asset';
import * as FileSystem from 'expo-file-system';

export default function App() {
  let [json, setJson] = React.useState('');
  let [parsed, setParsed] = React.useState('');

  React.useEffect(() => {
    async function loadContentsAsync() {
      let asset = Asset.fromModule(require('./example.json.lazy'));
      await asset.downloadAsync();
      let json = await FileSystem.readAsStringAsync(asset.localUri);
      setJson(json);
      try {
        let parsed = JSON.parse(json);
        setParsed(parsed);
      } catch(e) {
        setParsed({ hello: "UNABLE TO PARSE, INVALID JSON!"})
      }
    }

    loadContentsAsync();
  }, []);

  return (
    <View style={styles.container}>
      <Text>{json}</Text>
      <Text>{parsed ? `value of "hello" on parsed object: ${parsed.hello}` : ''}</Text>
    </View>
  );
}

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

You can also check out Brent’s repo here: https://github.com/brentvatne/lazy-json-example

Cheers!

5 Likes