reactjseager-loadingreact-component

Initialize / Eager Load React Component in Background on App Start for later usage


I'm writing a React App, where I have a Fallback component, which gets displayed when something goes wrong, for example: network is down, API isn't reachable, unknown route, etc.

This component will fetch some URLs of cat pictures and displays a slide show.

But of course this isn't possible when the network is down.

Though I'd like to somehow create and initialize this component in the background when the App starts, so everything is ready in the case of emergency.

Additional info: The Fallback component will be used as child component of different views. So it's not possible to simply mount it in App.jsx and use CSS visibility: hidden / visible to hide and display it.

Is this possible and does someone know how to do it?

EDIT: Example code

const Fallback = () => {
  // will contain urls like:
  //   - https://cats.example.org/images/foo.jpg
  //   - https://cats.example.org/images/bar.png
  //   - https://cats.example.org/images/42.gif
  const [urls, setUrls] = useState([]);

  useEffect(() => {
    fetch('https://catpictures.example.org')
      .then(response => response.json())
      .then(data => setUrls(data));
  }, []);

  // this should be cached somehow:
  return (
    <div>
      {urls.map(url =>
        <img src={url} />
      }
    </div>
  );
}

Solution

  • You can do this and I've done it in big production apps by simply creating a new Image() and setting the src. The image will be preloaded when the component is first rendered.

    const LoadingComponent() {
      useEffect(() => {
        const img = new Image();
        img.src = imgUrl;
      }, []);
    
      return null; // doesn't matter if you display the image or not, the image has been preloaded
    }
    

    It could even become a hook such as useImagePreloader(src) but that's up to you.

    Here is a Sandbox with a working version.

    Steps to try it:

    1. Create an incognito window, open devtools and check the network tab, search for "imgur". The image is loaded.
    2. Set the network offline or disconnect from your WIFI.
    3. Click on the Show Image button. The image will display correctly.

    This solution will always work provided your cache settings for images are set correctly (usually they are). If not, you can save the images to blobs and get a URL to that blob, that will work 100% of times.

    As you noted that you need an array of images, you can do that same code inside a loop and it will work just fine, images will still be cached:

    const images = ['first.jpg', 'second.png', 'etc.gif'];
    
    images.forEach(imageUrl => {
      const img = new Image();
      img.src = imageUrl
    });