4

I am using Coil with Jetpack compose. I noticed that in my LazyColumn items the images that load using coil(downloaded from the network) load faster when the device is offline ( this is once the images are cached of course ).

When the device is online, it seems coil is fetching the network copy even though a local cached version of that image exists.

I would like coil to prioritize fetching images based on the following order:

  1. Check if it exists in Memory Cache
  2. If not check if a Disk Cache exists
  3. If the above 2 don't exist then fetch from the network

How do I achieve this? My current ImageRequest Builder looks like this:

ImageRequest.Builder(LocalContext.current)
  .data(downloadUrl)
  .crossfade(true)
  .crossfade(coilFadeDuration)
  .error(R.drawable.black_color_rectangle)
  .placeholder(R.drawable.placholder)
  .fallback(R.drawable.black_color_rectangle)
  .networkCachePolicy(CachePolicy.ENABLED)
  .diskCachePolicy(CachePolicy.ENABLED)
  .memoryCachePolicy(CachePolicy.ENABLED)
  .diskCacheKey(downloadUrl)
  .memoryCacheKey(downloadUrl)
  .diskCacheKey(downloadUrl)
  .memoryCacheKey(downloadUrl)
  .size(Size.ORIGINAL)
  .build()
Anudeep Ananth
  • 955
  • 1
  • 8
  • 30
  • Are you sure? By definition coil won't download something present in the cache. – David Jun 18 '22 at 18:15
  • What is LocalContext.current? – David Jun 18 '22 at 18:22
  • @David I am certain it fetches data from the network if the internet is available. I've tested this by changing the image at the source ( server ), coil immediately fetches the updated image. "LocalContext.current" is the Context. – Anudeep Ananth Jun 19 '22 at 08:43
  • I have this flags set and it works on my side, yo there is something wrong in your implementation somewhere, maybe try removing all the CacheKey call. There is also a logging functinality with which you can see in Logcat where the loaded image is coming from, so you don't need to manually change something on the server to be able to check something. – David Jun 19 '22 at 08:49

1 Answers1

1

Coil cache relies on the cache-control and expires HTTP headers returned by the server at the time the request was first served to check if the image should be load from the cache or from the server...

If you cannot change the cache-control header value returned by the server then you still have the ability to rewrite the response using an okHttp interceptor like this :

ImageLoader.Builder(context)
    .okHttpClient {
        OkHttpClient
            .Builder()
            .addInterceptor { chain ->
                chain.proceed(chain.request())
                    .newBuilder()
                    .removeHeader("cache-control")
                    .removeHeader("expires")
                    .addHeader("cache-control", "public, max-age=604800, no-transform")
                    .build()
            }
            .build()
    }
    .build()

Now your cache (memory or disk) will be used during 604800 seconds = 1 week instead whatever max-age value that was previously returned by the server. (In my case the server is returning 1 day = 86400 seconds)

avianey
  • 5,545
  • 3
  • 37
  • 60