Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prioritise local cache over Network in Coil

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()
like image 950
Anudeep Ananth Avatar asked Oct 29 '25 07:10

Anudeep Ananth


1 Answers

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)

like image 121
avianey Avatar answered Nov 01 '25 12:11

avianey