Responsive design is now widely regarded as the dominant approach to building new websites. With good reason, too: a responsive design workflow is the most efficient way to build tailored visual experiences for different device screen sizes and resolutions.
Responsive design, however, is only the tip of the iceberg when it comes to creating a rich, engaging mobile experience.
The issue of performance with responsive websites
Performance is one of the most important features of a website, but is also frequently overlooked. Performance is something that many developers struggle with – in order to create high-performing websites you need to spend a lot of time tuning your site’s backend. Even more time is required to understand how browsers work, so that you make rendering pages as fast as possible.
When it comes to creating responsive websites, the performance challenges are even more difficult because you have a single set of markup that is meant to be consumed by all kinds of devices. One problem you hit is the responsive image problem – how do you ensure that big images intended for your Retina Macbook Pro are not downloaded on an old Android phone? How do you prevent desktop ads from rendering on small screen devices?
It’s easy to overlook performance as a problem because we often conduct testing under perfect conditions – using a fast computer, fast internet, and close proximity to our servers. Just to give you an idea of how evident this problem is, we conducted an analysis into some top responsive e-commerce sites which revealed that the average responsive site home page consists of 87.2 resources and is made up of 1.9 MB of data.
It is possible to solve the responsive performance problem by making the necessary adjustments to your website manually, but performance tuning by hand involves both complexity and repetition, and that makes it a great candidate for creating tools. With Capturing, we intend to make creating high-performing adaptive web experiences as easy as possible.
Introducing Capturing
Capturing is a client-side API we’ve developed to give developers complete control over the DOM before any resources have started loading. With responsive sites, it is a challenge to control what resources you want to load based on the conditions of the device: all current solutions require you to make significant changes to your existing site by either using server-side user-agent detection, or by forcing you to break semantic web standards (for example, changing the src
attribute to data-src
).
Our approach to give you resource control is done by capturing the source markup before it has a chance to be parsed by the browser, and then reconstructing the document with resources disabled.
The ability to control resources client-side gives you an unprecedented amount of control over the performance of your website.
Capturing was a key feature of Mobify.js 1.1, our framework for creating mobile and tablet websites using client-side templating. We have since reworked Mobify.js in our 2.0 release to be a much more modular library that can be used in any existing website, with Capturing as the primary focus.
A solution to the responsive image problem
One way people have been tackling the responsive image problem is by modifying existing backend markup, changing the src
of all their img
elements to something like data-src
, and accompanying that change with a <noscript>
fallback. The reason this is done is discussed in this CSS-Tricks post –
“a src that points to an image of a horse will start downloading as soon as that image gets parsed by the browser. There is no practical way to prevent this“.
With Capturing, this is no longer true.
Say, for example, you had an img
element that you want to modify for devices with Retina screens, but you didn’t want the original image in the src
attribute to load. Using Capturing, you could do something like this:
if (window.devicePixelRatio && window.devicePixelRatio >= 2) {
var bannerImg = capturedDoc.getElementById("banner");
bannerImg.src = "retinaBanner.png"
}
Because we have access to the DOM before any resources are loaded, we can swap the src
of images on the fly before they are downloaded. The latter example is very basic – a better example to highlight the power of capturing it to demonstrate a perfect implementation of the picture
polyfill.
Picture Polyfill
The Picture element is the official W3C HTML extension for dealing with adaptive images. There are polyfills that exist in order to use the Picture element in your site today, but none of them are able to do a perfect polyfill – the best polyfill implemented thus far requires a <noscript>
tag surrounding an img
element in order to support browsers without Javascript. Using Capturing, you can avoid this madness completely.
Open the example and be sure to fire up the network tab in web inspector to see which resources get downloaded:
Here is the important chunk of code that is in the source of the example:
Take note that there is an img
element that uses a src
attribute, but the browser only downloads the correct image. You can see the code for this example here (note that the polyfill is only available in the example, not the library itself – yet):
Not all sites use modified src
attributes and <noscript>
tags to solve the responsive image problem. An alternative, if you don’t want to rely on modifying src
or adding <noscript>
tags for every image of your site, is to use server-side detection in order to swap out images, scripts, and other content. Unfortunately, this solution comes with a lot of challenges.
It was easy to use server-side user-agent detection when the only device you needed to worry about was the iPhone, but with the amount of new devices rolling out, keeping a dictionary of all devices containing information about their screen width, device pixel ratio, and more is a very painful task; not to mention there are certain things you cannot detect with server-side user-agent – such as actual network bandwidth.
What else can you do with Capturing?
Solving the responsive image problem is a great use-case for Capturing, but there are also many more. Here’s a few more interesting examples:
Media queries in markup to control resource loading
In this example, we use media queries in attributes on images and scripts to determine which ones will load, just to give you an idea of what you can do with Capturing. This example can be found here:
Complete re-writing of a page using templating
The primary function of Mobify.js 1.1 was client-side templating to completely rewrite the pages of your existing site when responsive doesn’t offer enough flexibility, or when changing the backend is simply too painful and tedious. It is particularly helpful when you need a mobile presence, fast. This is no longer the primary function of Mobify.js, but it still possible using Capturing.
Check out this basic example:
In this example, we’ve taken parts of the existing page and used them in a completely new markup rendered to browser.
Fill your page with grumpy cats
And of course, there is nothing more useful then replacing all the images in a page with grumpy cats! In a high-performing way, of course ;-).
Once again, open up web inspector to see that the original images on the site did not download.
Performance
So what’s the catch? Is there a performance penalty to using Capturing? Yes, there is, but we feel the performance gains you can make by controlling your resources outweigh the minor penalty that Capturing brings. On first load, the library (and main executable if not concatenated together), must download and execute, and the load time here will vary depending on the round trip latency of the device (ranges from around ~60ms to ~300ms). However, the penalty of every subsequent request will be reduced by at least half due to the library being cached, and the just-in-time (JIT) compiler making the compilation much more efficient. You can run the test yourself!
We also do our best to keep the size of the library to a minimum – at the time of publishing this blog post, the library is 4KB minified and gzipped.
Why should you use Capturing?
We created Capturing to give more control of performance to developers on the front-end. The reason other solutions fail to solve this problem is because the responsibilities of the front-end and backend have become increasingly intertwined. The backend’s responsibility should be to generate semantic web markup, and it should be the front-end’s responsibility to take the markup from the backend and processes it in such a way that it is best visually represented on the device, and in a high-performing way. Responsive design solves the first issue (visually representing data), and Capturing helps solve the next (increasing performance on websites by using front-end techniques such as determining screen size and bandwidth to control resource loading).
If you want to continue to obey the laws of the semantic web, and if you want an easy way to control performance at the front-end, we highly recommend that you check out Mobify.js 2.0!
How can I get started using Capturing?
Head over to our quick start guide for instructions on how to get setup using Capturing.
What’s next?
We’ve begun with an official developer preview of Mobify.js 2.0, which includes just the Capturing portion, but we will be adding more and more useful features.
The next feature on the list to add is automatic resizing of images, allowing you to dynamically download images based on the size of the browser window without the need to modify your existing markup (aside from inserting a small javascript snippet)!
We also plan to create other polyfills that can only be solved with Capturing, such as the new HTML5 Template Tag, for example.
We look forward to your feedback, and we are excited to see what other developers will do with our new Mobify.js 2.0 library!
About Shawn Jansepar
@shawnjan8 Shawn is a software engineer at Mobify where he works on the open source Mobify.js library, and on the Mobify Cloud. He loves to hack both on the front-end and back-end, with a heavy focus on user experience. When he isn't hacking, you will likely find him playing hockey/video games, eating, or travelling. Shawn has a BSc in Computer Science from Simon Fraser University.
More articles by Shawn Jansepar…
About Robert Nyman [Editor emeritus]
Technical Evangelist & Editor of Mozilla Hacks. Gives talks & blogs about HTML5, JavaScript & the Open Web. Robert is a strong believer in HTML5 and the Open Web and has been working since 1999 with Front End development for the web - in Sweden and in New York City. He regularly also blogs at http://robertnyman.com and loves to travel and meet people.
34 comments