Progressive Image Loading using RxNuke

Sourav Chandra
3 min readApr 25, 2023

Users have grown accustomed to instant load times on most images they consume in the apps they use everyday. Companies like Facebook, AirBnB, Twitter and Instagram use many different techniques to make this possible.a

A beautiful and functional design is a paramount target for every growing app startups. When I see apps like AirBnb, Twitter, Instagram and Facebook it mesmerises my eyes every bit. Its not just the good UI though. There is something else which contributes to the UI. I tried digging deep and found some similarities, which they all share among themselves. The similarity is “Engaging Content!”

What could be different ways to generate engaging content? Well, it could be through various ways just like Facebook is endorsing videos and Instagram already has pictures. So, how is your app different from them? Even when you have engaging pictures or videos in your app. People might stick to Facebook and Instagram only.

Sometimes I just keep browsing AirBnb for wonderful destinations, even when I don’t have any plans for travelling.

The only reason is, when I open these apps I don’t have to wait for the content to appear. They all use lots of good quality images and videos as their content. But it loads within seconds. It’s ready to see even when you keep scrolling. The technique is called progressive image loading.

What is progressive image loading?

When you load your image sequentially from low to high quality instead of loading a high quality image at once, then its called progressive image loading. Today I will talk about how I managed to implement it in iOS.

I used a cool iOS library called RxNuke which basically provides Reactive extensions for one of the most popular image loading library Nuke in iOS.

Nuke is purely written in swift. See the benchmarks here

Image Variants

I have five versions of my image on my cloud storage (Firebase Storage). I use Firebase cloud functions to generate different variants. These versions are:

  1. Original
  2. High Quality (_high)[80% Quality]
  3. Medium Quality (_med)[50% Quality]
  4. Low Quality (_low)[25% Quality]
  5. Thumbnail (_thumb)[10% Quality]

Each one of the variant has a corresponding suffix assigned to it.

Let’s get coding!

I created a Nuke’s Manager extension in swift to deal with my image loading requirements:

Nuke can only download the image from an url, so I first convert my StorageReference to a simple downloadUrl. Then I flatMap the resulting url to RxNuke Manager to provide me with the proper UIImage object after downloading. I created 4 download streams to download the the image variants sequentially.

There could be a situation when my cloud function is still in process to generate my image variants and its not yet ready to download. As a fallback, I try to download my original image.

If everything else fails, I just return an error image from my local assets.

Tip: Converting a storage reference to download url requires internet connection. Even when the image is disk cached by Nuke, you might not be able to see it. To resolve this issue, you can use a download url caching mechanism using NSUserDefaults. This will also save the number of requests you are making for download url generation every time.

References:

  1. Nuke: An image loading library in Swift.
  2. Comparison of different image loading libraries in iOS: Benchmarks by kean.
  3. RxSwift
  4. Rx wrappers for Nuke: RxNuke.
  5. Rx wrappers for Firebase: RxFirebase.

--

--

Sourav Chandra

Entrepreneur, Philanthropist and Swift Enthusiast with natural interest in UI/UX.