Users today mostly consume multimedia content on their mobile phones because mobile networks are fast enough and data plans are getting cheaper by the day.
I remember when playing a single YouTube video via mobile data was a definite no-no, but now I would play an entire playlist without breaking a sweat. Does that mean we don’t have to pay attention to data usage when we develop our apps? Of course not!
Even if your users have larger data plans and they wouldn’t mind extra traffic from your app (but be assured, most of them will), there are other benefits of optimizing your data flow. It will result in faster data loading and making your app more responsive. Your users will love that!
Here are a few tips on what to keep in mind when developing an app. To keep it more interesting, I’ll base my examples on a recipe app. Let’s start cookin’!
API Data Structure
Model your API responses to deliver only as much data as it’s currently visible in the app. To explain better, my list of recipes should only contain the data that is needed for the list preview (title, photo, and maybe a time of preparation).
The entire recipe (description, ingredients, photo gallery etc.) should be loaded only if the user clicks on one of the recipes and a recipe single screen opens. This may seem like a small optimization, but if your lists are big, response times will increase and data loading from the server will become slower.
Prepare Images in Different Sizes
If your app features a list preview, let’s say a list of recipes, you’ll want to prepare thumbnail-sized images for those items. Those smaller images will load faster and the experience of scrolling through that list will be much better for the user. You can load the rest of the data along with the large-sized image only if the user decides to open a single recipe and explore that delicious meal.
When the user creates a new tasty recipe, you should automatically generate a smaller-sized image and store it alongside the original image. Your recipe model will then contain a thumbnail image URL as well as a URL for the large-sized image.
To go even further, it’s a good idea to prepare even more different-sized images, so your app can load the most appropriate one for the phone your user is using – depending on the screen size, resolution, current network quality etc.
Cache Images, Video and Music
It sounds a bit ridiculous to even mention it, but… cache the multimedia files!
Your app won’t have to download the same images over and over again, it will just load them from the cache storage. There are many image loading libraries which cache images automatically and you should definitely use them. For Android, those are libraries like Glide, Picasso or Fresco. For iOS, you’ve surely heard about Nuke or Kingfisher.
Don’t stop on just caching the images. Look into video and audio file caching libraries as well. You can use AndroidVideoCache library to make a cache proxy which enables you to stream and cache video and audio files.
Resize Images Before Upload
So, we talked about optimizing the data loading from the server, but remember to reduce the size of uploading files as well. Today’s phones can capture images in high resolutions with image file sizes over 2MB, but you probably won’t need the full-sized image. For chat apps and similar, an image resized to max.
1080 pixels of width or height will probably be more than enough to send. Also, if your app doesn’t mind some quality reduction, you can compress the images to reduce the file size even more.
Add a Local Database
Save all those recipes locally and seek to load them from the local database instead of loading it from the server. The best experience for the user would be to always instantly load the data from local database, request the data from the server at the same time, and replace the local data with the fresh one from the server and update the screen. That way, the user will have the content as soon he opens the app, with fresh content just a few seconds later. Just make sure that content swapping goes seamlessly, without sudden flicks or swaps on the screen. The change needs to be intuitive, so add some animations for the items that are added, deleted or that have swapped positions.
Minimize Automatic Background Data Loading
Sometimes, apps preload the data in the background. That way users always have fresh information instantly when they open the app. The problem is if you load large amounts of data periodically, and the user doesn’t even consume that data. For data usage optimization, it’s better to load the data only on user demand.
That being said, if you still have to use some background loading, at least try to check if the user is connected to the mobile network and postpone it until the user connects via WiFi. Even though this will be a small data usage optimization, users will be grateful if you try to save some of their data plan.
Use Platform-Specific Mechanisms to Reduce Phone Resource Usage
Somewhat similar to the previous tip, allow users to choose how and when your app loads the data, especially if your app is syncing with the server regularly. A nice feature for users would be to let them decide if the app will sync only on WiFi or on mobile data as well, while on battery or only when it’s connected to a charger or even let them choose how often those syncs happen.
Remember – you’re not only optimizing the data usage, you’re also optimizing the usage of phone resources in general (processor power, battery etc.).
Push Instead of Pull
If your app needs to refresh local data on a regular basis, use a cloud messaging service solution (Firebase etc.) to deliver new data directly to your app. That way you will avoid regular checks with the server if to see if there’s something new and get notified instantly. In that recipe app of ours, it’s recommended to send the entire recipe data via a push notification and store it locally. This way, besides just notifying your user about this new meal, the user is immediately updated with the latest data. Ideally, your app will always be fully synced and you can just load the data from the local database without pulling it from the server.
If your app features a large data list (or lists) with hundreds of items, you will need to implement pagination. Don’t load all of the recipes from the server, but only load first n items and load the next ones when users approach the end of the list. In our apps, we usually load 20 items at a time, depending on the size of a single item.
As for list refreshing, implement a last refreshed timestamp parameter which you can pass on to the server side. That way, a server will return only items that have been created after the requested timestamp and not entire page of items.
Does It Even Matter?
At the time, we didn’t feel this kind of optimization makes much difference, but in the last few years, even Google and Apple started integrating all kinds of solutions into their OS cores to maximally optimize usage of phone resources. We feel it’s important for developers to make their own contribution and try to optimize their apps as much as possible.
Feel free to share with us your thoughts about this topic and tell us about the ways you optimise your apps!