Skip to main content

Getting network images to appear faster in flutter app

This post is about how I got network images to appear faster in my Flutter app. In part 1 I detail all the things I tried to make this work. In part 2 I share what finally worked to solve this issue. 

The goal
In my Shopping List App I allow my users to customize the background picture for their list.  I want the background image that my users choose to persist no matter what device they are using to access their shopping list.

The problem
Originally the user's image choice was saved via Shared Preferences which saves the name and location of their background image on their device. But if they were to log into their account using another device their background image would default to the default image instead of their chosen image.

 To fix that I stopped using Shared Preferences and instead used Firebase Firestore to remember the name of the last image they chose. Then I wanted to save their custom uploaded images into Firebase cloud storage instead of on the device this way they can access their own images regardless of device.

 So I got everything to work but when you go to a list that is downloading a custom picture from the cloud storage it takes a full 5 seconds before it appears. 

There is just a grey background and no indication that their picture is loading. 

I need to fix that because my users will think that my app is broken because it takes so long for their image to show up. 

Attempt #1
So the first way I will try to solve this problem is to precache the image before the user gets to their list. 
There is a function called precacheImage( ). My plan is to use that in the onPressed function of my Flatbutton. 
I am saving the precacheImage( ) into a variable called bground. I put the variable in  Navigator.push( ) so that it will send the preached image to the next page. However it tells me that bground is void and cannot be used.
I think that is because it holds a future. Maybe I can get around this by putting the precacheImage part in a function. 
I placed the image inside of the build context since it requires a context.  In the function I am passing the variable that holds the image reference that is stored in Firebase Firestore. I also got rid of the variable bground and I am instead using saved. Saved is already defined inside my onPressed so it should work better. 
cacheThatImage(var image) async {
var saved = await precacheImage(NetworkImage(image), context);
return saved;
}
onPressed: () async {
await getBackgroundPic(listName);
var saved = setpic['picture'];
await cacheThatImage(saved);
var cust = setpic['custom'];
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ShoppingListPage(
listName: listName,
backgroundPicture: saved,
custom: cust,
)));
},
So it worked. It loaded the image faster but it took longer to get to the list page. I could add a circle progress indicator so that the user knows that something is happening in the background and that the app is not broken. 
Another issue is that when it does finally go to the list page there is still a brief moment of a grey screen. 

So next I will work on adding the circle progress indicator and maybe having a placeholder image so they know that the image is still loading. I wonder which problem I want to have. The list taking a while to load or the image taking a while to load. 

Comments