Web engineers who are serious about performance know that the majority of the web-performance bottlenecks are in the frontend. The biggest issues are the number of HTTP requests, heavy external resources, and blocking the UI thread resulting in either a momentary Flash Of Unstyled Content (FOUC) or the perception of an unresponsive site. A fast website equals better search engine rankings, higher conversion rates and even saves costs.
In this post, we’d like to talk about how we tackle the problem of reducing the number of HTTP requests. Compared to optimizing heavy external resources and unblocking the browser’s rendering engine, these are easier to make and have the biggest impact on performance.
If you’re ready to bring these performance enhancements to your website today, check out Mobify Cloud for free.
Thinking about HTTP Requests
The ideal case is of minimizing HTTP requests is to have two requests: one for an external script and one for an external stylesheet. Why?
- Every external script file has the potential to block the DOM tree
construction as scripts can have a
document.writethat changes the DOM.
- Browsers stall when they encounter an external stylesheet because
CSS files can have embedded
@imports(or lead to the aforementioned FOUC, which is bad user experience.)
In fact, Steve Souders, the guru of website performance recommends that
@import for high performance websites.
The problem with increased HTTP requests is exacerbated on mobile as each HTTP request can have a high variance in latency. It has become crucial to have some kind of post-development build process to optimize external resources before deployment to production. In development, it’s a good practice to organize your application into several files as debugging a giant monolithic file is a pain.
At Mobify, these are the kinds of issues that we like to solve with automation.
Challenges with naive concatenation
As much as we might wish it to be simple, combining files is not as simple as appending the start of one file to the end of the previous.
With CSS, the problem is different external files can have different
character encoding. Most CSS files are encoded in UTF-8, and we're
working on adding support for non-UTF8 character sets. Secondly, all
relative URLs must now be rewritten to be absolute URLs. Thirdly, the
CSS grammar only allows for
@import statements at the very top of the
file, so we’ll have to walk the dependency tree and “flatten” out the
hierarchy of imports.
Jazzcat: a resource concatenator
Jazzcat is a backend service we built to concatenate resources properly dealing with the caveats mentioned earlier. Upon receiving a request with a list of resources to fetch, Jazzcat makes individual requests to your website. The responses from your website are appropriately encoded before being returned to the client making the request. As with any proxy, we need to deal with issues like missing resources, unresponsive/slow backends, etc. We are able to handle thousands of concurrent open connections thanks to the evented architecture of Node.js.
The Jazzcat service itself is stateless, but we built a caching layer by putting a CDN in front of it. The CDN caches the combined files on distributed servers across the world, bringing it closer to the user. The CDN is also responsible for sending down gzipped versions of the final files to clients that support compression.
Taking caching to next level with Mobify.js
Mobify.js is our framework that helps you quickly adapt any website to any device. It's open-sourced under the MIT-license.
The next time a web page tries to load a script, Mobify.js first tries to see if local storage has it before making a HTTP request. If that page on your site requires a different set of scripts, Mobify.js progressively reduces the files it needs to fetch before making a single request to Jazzcat to download the missing files.
In some ways, you can think of the single connection as a pipeline to Jazzcat to stream new resources (aside: both Google and Bing use local storage to improve the performance of their respective websites.)
We’ve described from first principles how we attempt to reduce the number of HTTP requests, following best practices.
To make use of these advanced features, try the Mobify Cloud now for free.
And if you find this kind of work interesting, please consider applying to work at Mobify – we’re hiring.