Is anyone able to point me to an example of preloa...
# compose-web
c
Is anyone able to point me to an example of preloading images with Compose-HTML?
I came up with this, which seems to do the trick:
Copy code
@Composable
  fun ImgPreload(url: String, onLoaded: () -> Unit = {}) {
    val signal = Semaphore(1, 1)
    LaunchedEffect(url) {
      val img = Image()
      img.onload = {
        signal.release()
      }
      // This will start the load
      img.src = url
      signal.acquire()
      onLoaded()
    }
  }
a
Why use semaphores? It sounds to me this can easily be done with suspendCoroutine?
c
First time I've converted a callback to suspend function so I wasn't aware of it, thanks! Though that made me realise I'm effectively doing callback -> suspend -> callback which isn't needed. Also, seems like I'll have to hang on to the img reference so the browser doesn't GC/release the image again.
a
You could just attach them to a global window object, and let go of the reference. A bit dirty. Or, you create an image preloader which does that for you but still keeps the references.
c
Yep I've done the latter, just a circular array that holds the last 10 preloaded references. Should be plenty good enough for my purposes
For anyone interested:
Copy code
object Preloader {
  // A cache of preloaded images. We never look in this cache, it's just here to prevent
  // the browser from garbage collecting the most recent preloads.
  private const val IMG_CACHE_SIZE = 10
  private var imgCacheIndex = 0
  private val imgCache = arrayOfNulls<Image>(IMG_CACHE_SIZE)

  fun imgPreload(url: String, onLoaded: (Event) -> Unit = {}) {
    val img = Image()
    imgCache[imgCacheIndex] = img
    imgCacheIndex = (imgCacheIndex + 1) % IMG_CACHE_SIZE
    img.onload = { event ->
      onLoaded(event)
    }
    // This will start the load
    img.src = url
  }
}