Progressive image loading in React Native

An experiment to improve image loading experience on slower connections.

Bottom line on top:

Here’s a screencast of a simulated 3G experience. The basic Image component is used on the left pane and a custom component on the right. Like the enhanced experience on the right? Read on.

Simulated 3G network. Left: Basic ; Right: Progressive

I started working on an image centric app recently and quickly realized that the default Image tag is plain when it comes to user experience. When loading a decent size image, depending on the connection, it could take a few seconds before the image is available. I wanted something similar to how Medium loads an image — show a gray placeholder before the image is loaded and gradually fade in the image. For example, this is the experience when loading an AWS S3 hosted 148KB image from eatornotapp.com on WiFi.

As you can see, the image load and render is not particularly pleasant. There are primarily two reasons

  1. The image takes a bit to load
  2. As soon as the image loads, it is presented immediately which causes a “flash”

Here’s the code used for the test

Loader component (gist)

My first step was to avoid the “flash” by writing a custom FadeInImage component to display a tiny fade in effect by hooking into the onLoad event of the Image component.

This was great! Already feels better than what I had before. Here’s the code for the custom FadeInImage component. This can be easily tweaked to produce other effects.

FadeInImage.js (gist)

However, this still isn’t a great experience on a slower connection. You see the placeholder for a few seconds before the actual image is available. So, I went back José Manuel Pérez’s excellent post on how Medium implements progressive image loading. This is also somewhat related to how Facebook implements image loading on mobile. The idea is simple — create a tiny thumbnail to display as a placeholder. In order to avoid pixelation, blur it! Now, the thumbnail is 4KB compared to the original 148KB image.

Now, the ProgressiveImage component does two things, loads the thumbnail first, then loads and fades in the actual image when its ready.

Not too bad. However, you’re not seeing the real benefits since its on WiFi. Lets see the same image loading on 3G.

Tadaaa! Now, that’s exactly what I wanted!

Here’s the code for the ProgressiveImage component.

ProgressiveImageComponent.js. (gist)

To sum up, we went from a jagged slow image load and flash to a progressive pleasant image loading experience!

Simulated 3G network. Left: Basic ; Right: Progressive

Thanks for reading the post. Please provide any feedback/comments below or tweet at @sharathprabhal


Hit the recommend button if you want others to read this.

Check out other interesting React Native articles at