Optimally preloading / prefetching images in UICollectionView and UITableView

Viewed 2281

I have what I would imagine is a very common situation that I expected to be easy to solve - an app with a UICollectionView, with an image in each cell that is fetched from an API on a web server via http/https.

I'm attempting to implement iOS 10's prefetching in UICollectionView, so that images are that are likely to be required are requested ahead of time.

It seems to me that there are various requirements that should be met for optimal prefetching:

  1. Fetching of images that are actually immediately required should always be prioritised above speculative prefetching, even when the image is already in a queue to be fetched.
  2. When iOS tells us a particular image is no longer required to be prefetched, it (and only it) should be removed from the prefetch queue.
  3. If an image is requested it should always be delivered unless /all/ requests for it are canceled (easy to get wrong if one image is used in multiple cells or multiple view controllers).
  4. Prioritised fetching should be aborted if didEndDisplaying is called (but, if prefetching was requested and wasn't cancelled, the image should presumably be left in the queue at a lower priority).
  5. Various common requirements that simply relate to image loading - eg. don't flood the underlying system with prefetch requests that will end up taking bandwidth and server slots away from images that are required immediately.

I've looked at various existing libraries like SDWebImage and Kingfisher, and was surprised that there doesn't appear to be any way to meet the above requirements easily with either library.

For example, SDWebImage doesn't meet the second requirement - you can only cancel all prefetching, or you must create a pre-fetcher per image (which then means various other SDWebImage features, like limiting the number of concurrent requests of pre-fetched images - ie. requirement 5 - no longer work.)

Is this really a hard problem? Did I miss some obvious solution? Am I overthinking the requirements?

1 Answers
Related