Hammering #perf issues in Simpl Checkout

Simpl
Simpl - Under The Hood
4 min readSep 7, 2016

with first principle

This article summarizes three approaches we’ve used to gain speed improvements to delight our customers using Simpl on various merchants. Simpl enables merchants to make more transactions online, while making the process effortless for customers. If you’ve not used Simpl before, I highly recommend to checkout a list of merchants we support.

Investigate #perf issues

Identifying issues and accepting their existence can be a difficult part of a life, especially when someone else points them out. We were initially under the impression that a mere 100+ KB for our Simpl checkout page should load blazingly fast, until one of our big merchants pointed out that it is not so, mostly on low-end devices. Without further ado, we decided to dig in for clues. Soon after analyzing the network data in Chrome DevTools, we found “Latency” a real culprit!

Take a moment to refer the top 5 HTTP requests in the screenshot above. Even though the file size of each request is only a few KB, it takes up most of the load time. To resolve the latency issue, initial discussions revolved around moving the AWS servers in India. Although this might have given instant speed boost without touching the code but it was a complex and a time consuming process that needed to be done without affecting live users.

There are many solutions to a single problem — anonymous

Using the above philosophy, we decided to tackle the problem in a different direction and that is by touching the code ;-). Our first challenge was to change users’ perceptions about speed.

Improve perceived performance

No one likes to wait to get to Point A from Point B. And even if it is going to take a bit longer, showing a little progress made towards the goal is always satisfactory. In the following video, a native loader is visible for quite a long time until page loads completely.

Note that we can not get rid of the delay without downsizing the page to load it faster, that’s where perceived performance comes into play. The perceived performance helps users believe that the wait is over and they are closer to their destination. There was a great study conducted by researchers from the Human Computer Interaction Institute at Carnegie Mellon University on the same line.

Based on the paper, to improve the perceived performance we decided to hide the native loader as soon as web-view kicks in and show the HTML based loader instead (which is part of the actual page itself). This assured that the actual page will be shown immediately once pending assets are fetched. Here is the fake HTML loader we used:

Note that we’ve improved perceived performance for users, but the overall duration for the complete page load has not changed.

Inline static assets to reduce network overhead

Now the obvious thing to do was to load remaining assets as quickly as possible. Traditionally, that’s where bundling (concatenating multiple JS files into one) helps. However, in our case the real problem was latency so the bundling did not help much. We soon came up with a naive but practical approach to bust the latency problem i.e. to inline JS/CSS used by the page. You may have already guessed that with this approach we will loose out on benefits of browser-based caching for assets, but for us the cost of the latency was way more than the benefit of the browser caching. Additionally, inlining smaller assets do not deter page loading much.

There are plenty of Gulp/Grunt/Brocoli plugins to inline JS/CSS during a build process, but we’ve used a simple rake task to do so.

Defer external web-fonts

We did not stop there..! We also found an issue with web-fonts that may sometimes block rendering of the text causing problems to the HTML-based loader we’d used earlier over native one. FTR, we serve the Source Sans Pro font directly from Google CDN using the following snippet:

WebFontConfig = {
google: { families: ['Source+Sans+Pro:400,600'] }
};
(function(d) {
var wf = d.createElement('script'), s = d.scripts[0];
wf.src = '//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
s.parentNode.insertBefore(wf, s);
})(document);

So we moved it under the window.load event in order to load external fonts at the end. This helped us to show the HTML-based loader instantly in the web-view. Going forward we may dispose the external fonts altogether and reuse the default system fonts. We’ll pursue our efforts in continuous improvements further.

Summary

In this article, we’ve covered a few unconventional ways to gain speed performance improvements which may not be holy grails for some of you who are reading the article currently. However, these approaches may yield great benefits for small size apps.

For us, new features are great but a well running app is even more important. That’s why we made the Simpl checkout flow blazingly fast (2x faster) even on low-end devices. After all, Speed is a feature too — let’s not forget that :-)

--

--