August 8, 2022
The Internet has become ubiquitous over the last several decades, but there are still large regions around the world where network connectivity is a luxury. How do you, as a developer, best design your app for users in these regions?
The first thing to understand is how poor network conditions can affect a regular app’s performance.
Usually, the first noticeable symptom is slowness - any feature that requires an internet connection will become sluggish and take many seconds to load. Image loading will especially suffer since they naturally contain more bytes of data than plain text, and if the network conditions are bad enough they simply won’t load.
Next, if the network connection is truly unstable, the app may fail to work altogether and return a generic ‘You are offline’ error message. You may have to click the ‘Retry’ button many times before you are able to load anything, but even then you will probably lose connectivity again soon after.
The key to designing for poor connectivity is not just about optimizing for bandwidth and trying to compress everything as aggressively as possible - instead it is about preserving as much of the core functions your users need as possible and ensuring their core user journey is affected as little as possible.
Here are a few practical ways to preserve core functions in your app:
Perhaps the most intuitive strategy to combat poor network conditions is to simply abandon the network altogether. While most apps today cannot completely function offline, many key features within those apps can.
Local data storage is one of the key tools to enable offline functions. As an app developer, you have the option to save files and user input data locally on-device, and in many situations this is sufficient to enable features to work offline.
Take Google Docs, for instance. When you lose your connection, docs are still editable offline (assuming you enabled Offline Mode of course) as a locally-saved file, and when your connection is restored your offline edits will be synced automatically to the Google Docs servers. It all works seamlessly as if you never lost your internet connection in the first place.
Sometimes offline functionality is just about providing the illusion that a feature works, and as long as your users are still able to get substantial value out of our offline features you have done your job right.
Caching is another obvious optimization that comes to mind. By caching data and files in your device’s local storage, you can serve them to users much faster and without a network connection.
For example, consider a news app that retrieves news articles (text) and relevant images from a server. The first time the app obtains data from the server, it can save the text and images locally, and if a user reloads the app without internet connection the locally-cached content can be displayed immediately instead of rendering an error message.
By caching data on-device, your app will also use less data overall. This can be important in certain countries where data plans are expensive with the local mobile carriers, and users often have no idea how much data they’re using until they get a hefty bill at the end of the month.
Images are some of the most expensive assets to load in poor network conditions, so any optimizations to load them faster can yield significant performance increases.
First, not all image formats are created the same. Typically JPEG offers good compression (smaller size) and good quality through lossy compression versus PNG, which maintains perfect quality (lossless compression) but at a cost of larger image size. There are also vector-based image formats such as SVG, which results in even smaller file sizes.
The dimensions and resolution of images also contributes to file size, and images should always be sized to their respective applications. There’s no need, for example, to load a 2000x2000 pixel image only to display it in a 100x100 thumbnail image container - improperly-sized images often result in unnecessarily long load times.
Finally, for simple graphics, consider using CSS (for web apps) or other rendering methods instead of downloading images from the internet. Only use an image when it is absolutely necessary.
Contrary to images, text is one of the least data-intensive formats to send over a network. Text characters are just bytes of data, so it takes a lot fewer bits of 1’s and 0’s to transmit entire paragraphs over a network than sending a single image.
For poor-network conditions, it makes sense to rely more on text as it will be quicker and more likely to load. This is also why websites tend to load blocks of text sooner than pictures or videos.
If your app, for instance, renders images of infographics containing text, it might be prudent to have a fallback implementation to just retrieve and render the text directly if network conditions are spotty.
Finally, some companies have chosen to build a separate ‘lite’ app altogether that strips away any unnecessary functionalities and only preserves the core functions. These apps are usually more lightweight, use less data, and don’t use a lot of on-device storage.
Facebook (now Meta), for example, has a Facebook Lite app that is a smaller version of the main Facebook app. Facebook Lite was designed to work in 2G conditions (very slow internet speeds compared to 4G LTE or 5G), allowing users to post, view friends’ posts, and stay connected on social media, all of which are core user journeys for the company.
There are, however, disadvantages to the Lite app approach. It adds a substantial amount of maintenance overhead to the engineering team because there is now an additional app that needs to be supported, updated, and released in conjunction with the main app.