We were wrong. Our users preferred to look at a blank screen until the application was ready to be used over being able to interact with it while it was not completely started.
After some careful analysis, we noticed three problems:
- There was a bug in our search field that caused user input to be removed upon application initialisation.
- We were loading a lot of lower priority resources before actually starting to load our application.
- The size of our assets was too big and took a while to load on a 2G connection.
The first problem was easy enough to solve. We located the bug and are currently testing the fix. However, the other problems required a plan, and we needed every team to contribute to an improvement of the situation.
Before going into the plan itself, let me share the result with you:
As you can imagine, I am quite excited about this result, especially because we still have some improvements in the queue.
So, how did we achieve this?
Step 1: Reduce asset size by loading features on demand
One of the reasons why we invested into adopting Webpack as our asset bundler is because of its integrated ability to load parts of our application on demand. We have been using this for quite some time, however, this time we actually implemented it for some of our more prominent, and complex, features like Slideouts, Gallery, Filters, Maps and others.
We also created separate build targets for the two versions of our search field that we were testing at the time and rewrote some simple but expensive code parts.
Our users loved this improvement and we saw an almost 2% increase in revenue on mobile devices.
Step 2: Asset caching
One way to deliver large assets faster is to just allow the user to cache them locally. In the past, every single one of our releases invalidated the user's cache due to changing file names. Again, just by using the tools that Webpack provides for us, we were able to implement long term caching for our assets so that users only need to download them again if they were affected by the current release.
As a result of this change, our users have been able to load our base libraries from cache for the last couple of months.
Step 3: Inline SVG icons
Introducing SVG icons instead of CSS sprites was a big win for our developers, designers, and a key element of our famous Project Ironman.
While this had already been an improvement, we decided to take it one step further and instead of loading the SVG icons as part of a CSS file, we decided to implement inline SVG icons with a fallback solution for browsers that don't support SVGs. My colleague Radovan Janjic will soon offer a follow up article, describing the challenges we faced during this project and also explaining the benefits we'll gain from it in the future.
For now, let me just summarize by mentioning that we got rid of another ~14% in asset size and gained 10% in time to first render.
Step 4: Prioritizing users over collecting data
As any other web app out there, we need to do some user tracking for our analytics to work. Without the data, we can't improve the website for our users.
All of our trackers were being loaded async and should not have blocked anything. However on a slow connection, there is only so much data that can be downloaded at any given time. Especially on 2G connections that meant that the trackers were practically blocking the load of the application.
The real question here is not whether we really need to do it. In reality, the question boils down to priorities. Does it matter more to collect the necessary data or is it more important to offer a pleasing user experience?
At trivago, there was no discussion. As soon as we proposed to prioritize the application startup over loading our trackers, we got the green light.
As shown in the image above, this change reduced the time for loading 3rd Party resources quite a lot.
The result, once again, was pleasing. We were able to save a lot of time during startup on slow connections just like we expected.
Step 5: Delay loading of images
Are we done yet?
Well, of course not. But these steps have already lead to a massive improvement and we managed to do all of this with a coordinated effort from all of our teams without impacting their usual feature development work. We also managed to get all obstacles out of the way so that the browsers can start loading our assets as soon as possible even if they are on a slower connection like 2G or 3G.
Don't know about you but I will have an Espresso now.