If you’re coding an Android app and using the fantastic Glide library to load images in a RecyclerView, you’ll probably Google [glide recyclerview] to see if there is any gotchas like potential memory leaks or something. The first result in the SERP is the Glide docs about using RecyclerViewPreloader to load images ahead of a user scrolling. It’s kind of complicated to integrate and when I was setting it up, I asked myself is it even worth the bother compared to the gloriously simple Glide.with(view.context).load(url)
?
After investigation, I’m going to say a reluctant yes if a lot of your users will have poor Internet. If most of your users have good Internet, then it really makes no difference.
I recorded videos of an Espresso test that loads the RecyclerView fragment, on the left with no preloader and on the right with it enabled. Both tests are the same otherwise; sleeps for 15 seconds to give a chance for the preloader (or not) to work its magic, scrolls 10 times through the list while sleeping 1.5 seconds every scroll before finally sleeping 5 seconds at the last position. The Espresso tests were run on a tablet with Charles proxy throttling the connection at 1megabit. I put both videos side-by-side while trying to lineup the scrolls as closely as possible, it’s a small bit off but it’ll do:
You can judge the results for yourself. Sure, the preloader on the right does do something on a throttled connection of 1megabit while the user is scrolling through quickly. But at the end when the user stops for 5 seconds, the normal Glide has loaded a few images as you’d expect. I would say this is sufficient as a low bandwidth user probably only wants images to load where they’re spending time looking at.
Remember this is on a throttled connection. On most phones with good internet that can play Youtube videos all day, none of this matters and the preloader is definitely not worth the hassle.
Memory cache EngineKey
Another thing I noticed is how easy it is to miss the cache. Your EngineKey hashcode for your image in your preloader has to match exactly the image that’s loaded in the onBindViewHolder
or else it’ll be a fresh load. You can verify this by turning on Glide logging with adb shell setprop log.tag.Engine VERBOSE
and checking your LogCat for either ‘Loaded resource from cache’ or ‘Loaded resource from active resources’ for a memory cache hit or ‘Started new load’ for a miss. Your preloader and bind code might match exactly but the bind might implicity do a transform which will mean a different hashcode for the image. I had to specify .dontTransform()
and .override(640,640)
in my code.
But it actually doesn’t really matter if Glide has to do a fresh load as the preloader has already saved the image to the disk cache assuming you got the URLs the same at least. So it’s probably not even noticeable.
Remember that RecyclerViewPreloader is for caching images in memory which in turn caches images to disk. But there’s easier ways to cache to disk only.
These are just a few of my findings while playing with Glide. It’s very possible I got things very wrong, so correct me in the comments if I did.