Stelios Papamichail
Stelios Papamichail

Reputation: 1270

Glide loads images from firebase painfully slow using URLs

I'm trying to create a RecyclerView that is populated by ImageViews in each cell and each image corresponds to an image in Firebase Storage. I have a list of Strings that is passed into my RecyclerView adapter and each one represents a URL to an image in Firebase Storage. I load each image inside the onBindViewHolder().

What i get in return is a very VERY slow loading of a few images (around 5-see picture) and then it takes around 4 minutes to load another 5 and it never seems to load any other images after these.

I've read multiple posts on StackOverflow but most of them just tell you to use fitCenter() or centerCrop() but that doesn't change anything in my case. I also read in Glide's documentation that Glide will automatically downsample your images so i shouldn't need to do it manually, right? Any ideas what i could be doing wrong here? The Url Strings are successfully retrieved from Firebase and the queries are resolved almost instantly so i don't think there is any issue there.

UPDATE: I've made some modifications in the onBindViewHolder() method in order to explicitly request caching of the images from Glide and i also used the thumbnail API to download lower resolutions of the images. Now more images are loading but each one still takes around 7 seconds to load which obviously is too long. If you have any suggestions let me know please.

Here's how the RecyclerView is set up in my main activity:

iconsRCV = findViewById(R.id.cardIconsRCV)
iconsRCV.layoutManager = GridLayoutManager(this,5) // set the layout manager for the rcv
val iconUrls : ArrayList<String> = ArrayList() // initialize the data with an empty array list
val adapter = CardIconAdapter(this,iconUrls) // initialize the adapter for the recyclerview
iconsRCV.adapter = adapter // set the adapter

Note that i get new data when certain queries are done and then i call adapter.notifyDataSetChanged() to pass new data to the RecyclerView.

CardIconAdapter.java:

public class CardIconAdapter extends RecyclerView.Adapter<CardIconAdapter.ViewHolder> {

private  RequestOptions requestOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL).centerCrop().error(R.drawable.applogotmp);
private List<String> urlsList;
private Context context;

class ViewHolder extends RecyclerView.ViewHolder {
    ImageView iconImg;
    ViewHolder(@NonNull View view) {
        super(view);
        iconImg = view.findViewById(R.id.cardIcon);
    }
}

public CardIconAdapter(Context cntxt, List<String> data) {
    context = cntxt;
    urlsList = data;
}

@NonNull
@Override
public CardIconAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view =  LayoutInflater.from(parent.getContext()).inflate(R.layout.card_icons_rcv_item,parent,false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull CardIconAdapter.ViewHolder holder, int position) {
    GlideApp.with(context).load(urlsList.get(position)).apply(requestOptions).into(holder.iconImg);
}

@Override
public int getItemCount() {
    return urlsList.size();
}
}

result

P.S. The image sizes in Firebase are mostly udner 200KB but with a small few reaching 4MB. Also, the ImageView in the R.layout.card_icons_rcv_item layout is 75x75 in size.

Upvotes: 0

Views: 2457

Answers (1)

Radhey
Radhey

Reputation: 2229

Hope you have used latest version of glide. There are few ways for better image loading and caching, credit goes to this nice article .

1. Enable Disk Cache

 val requestOptions = RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL)
 Glide.with(context).load(url).apply(requestOptions).into(imageView)

2. List item

val requestOptions = RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .signature(ObjectKey(signature))

Glide.with(context).load(url).apply(requestOptions).into(imageView)

3. Override Image Size (Optional)

val requestOptions = RequestOptions()
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .signature(ObjectKey(signature))
        .override(100, 100) // resize does not respect aspect ratio

Glide.with(context).load(url).apply(requestOptions).into(imageView)

4. Add Thumbnail Url

// With thumbnail url
Glide.with(context).load(url)
        .thumbnail(Glide.with(context).load(thumbUrl))
        .apply(requestOptions).into(imageView)

// Without thumbnail url

// If you know thumbnail size
Glide.with(context).load(url)
        .thumbnail(Glide.with(context).load(url).apply(RequestOptions().override(thumbSize)))
        .apply(requestOptions).into(imageView)

// With size multiplier
Glide.with(context).load(url)
        .thumbnail(0.25f)
        .apply(requestOptions).into(imageView)

5. Setup Monthly Schedule for Cleaning

// This method must be called on the main thread.
Glide.get(context).clearMemory()

Thread(Runnable {
    // This method must be called on a background thread.
    Glide.get(context).clearDiskCache()
}).start()

6. To Transform bitmap

      // TODO remove after transformation is done
        .diskCacheStrategy(SOURCE) // override default RESULT cache and apply transform always
        .skipMemoryCache(true) // do not reuse the transformed result while running
        .diskCacheStrategy(DiskCacheStrategy.ALL) // It will cache your image after loaded for first time
        .format(DecodeFormat.PREFER_ARGB_8888) //for better image quality
        .dontTransform() // to load image faster just skip transform 
        .placeholder(R.drawable.placeholder) // use place holder while image is being load

Upvotes: 2

Related Questions