App Optimisation for Readle
This week's issue of Optimised will be a bit different. Rather than drill into a particular performance related topic, I'll be sharing a recent client project I worked on. Hopefully real world examples like these can provide practical insights for tackling performance issues on your own websites.
This article was originally published on my personal website. I have slightly edited it for this newsletter.
I've cut my teeth in website-related performance and optimisation. So I was a bit reluctant when Christian Schraeder, the founder of Readle, reached out for my help on their native mobile apps. I'd never worked on a mobile app before and wasn't too sure if I'd be able to help.
As it turned out, a lot of my knowledge of website performance and optimisation enabled me to identify key areas for improvement within the app.
What is Readle?
Readle is a language learning app available on both iOS and Android. Rather than simply giving learners a list of vocabulary to memorise, Readle delivers a more immersive experience. Across over 500+ short articles (all with audio) language learners can expand their vocabulary, test their comprehension, and track their progress.
When Christian first reached out to me, Readle was seeing steady growth in downloads and new user acquisition. At the same time, they were also receiving a growing number of complaints from users that interactions within the app were frustratingly slow - especially in East Asia, and the US. Christian was keen to address these speed issues. He knew it was important to his plans for expanding the app and continued growth.
After a quick onboarding, I started diving into the app. My initial aim was to identify and prioritise the areas within the app that might be contributing to slowness. Two things stood out:
- Response times for data requests - Requests for data inside the app were being sent back to the origin server on every request. This created around a one-second roundtrip as the request was made, after which the data was downloaded. This happened each time an article was opened, a word selected, or an audio clip played.
- The size of data being returned - The data being returned by these requests, especially on the initial app load, was a significant chunk of JSON data. Downloading and parsing this data slowed the initial app load time. The same was found when articles were opened, with surplus data being sent down the line.
Improving app speed
Working alongside Marcel Kipp, Readle's app developer, we set about the task of improving the speed of key areas. We focused on the following parts of the app:
- App launch
- Opening articles
- Selecting words
These are the three actions within the app that users will regularly make, especially new users trying the app for the first time.
Reducing data to improve performance
Starting with the app launch, we were quickly able to identify a major performance bottleneck. The app was downloading way more content than it actually needed. After going through the JSON data, Marcel was quickly able to identify which fields were surplus to requirements. Removing these extra fields, and reducing the number of articles being sent from 100 to 50 resulted in:
- A 1.5 second reduction in app launch time
- A greater than 10x reduction in data transfer size (from over 100kB to 10kB)
We undertook a similar process for articles data. Again, Marcel was able to reduce the data being sent. He also consolidated most of it into a new API. The savings here were not as large as for the app launch. We took about 2kB off the data transfer. This didn't directly improve the load time of article content but set us up nicely to start reducing the response time for requests.
Faster content delivery with Cloudflare
With data sizes reduced it was time to tackle response times. With every request being sent back to the origin server, responses were taking around 800 milliseconds to be returned (that's before downloading the data). This was a large source of frustration for users who were otherwise really enjoying the app.
We looked into a few possibilities to get this time down. We discussed an approach that would use a distributed database to better serve users around the globe. After some investigation, we decided to go down a different route - to cache as many of the requests as possible. Requests on the app were already passed through the Cloudflare network, which meant we could use Cloudflare page rules to set edge cache durations for different request types.
With caching in place we began seeing:
- A further 1-second improvement in app launch time
- Story (article) content ready for the user in under 200ms
- Word content shown to the user in under 200ms
- Audio content ready for playback almost instantly
We also started seeing positive app reviews - especially from users based in Asia!
Some image optimisation to boot
The one other significant change we made in the app was centred around image optimisation. After looking into some options that could have seen us put image optimisation into Readle's backend CMS, we opted instead to use Cloudinary. This enabled us to:
- Optimise images
- Deliver images in the best format (JPG or WebP)
- Cache images on a global CDN (speeding up delivery to the user)
Testing on an Android phone, images were being served using WebP format. Total image file size at launch was reduced by around 100kB. Response times for image requests also fell by 600ms on average.
The potential energy savings of deprecating Cloudflare's __cfduid cookie.
Cloudflare recently deprecated their __cfduid cookie. It's one of the web's most prevelant cookies, and in this article Nic Mulvaney takes a look at the data savings and potential CO2 reductions resulting from Cloudflare's decision.
The next issue of Optimised will be in your inbox on June 11th. The website has an archive of all previous emails. It's a good place to recap on anything we've covered, and also handy to share with friends or colleagues.
As always if you've got any feedback or specific topics you want to be covered then just reply to this email.
Keep safe, stay well.