In previous articles in our Responsive Web Design series we discussed the challenges associated with Responsive Design that are typically encountered and some simple recommendations for being successful with Responsive Design. In this article we’ll present a design approach that can be used to improve the performance and maintainability of a website while retaining its ‘responsiveness’ to device diversification that we have begun referring to as Responsive+.
While working on this article, we came across a post by Boris Smus on “A Non-responsive Approach to Building Cross-device Webapps“. While it tries to address some of the underlying issues with Responsive Design, it still does not provide a comprehensive solution that solves all the issues.
Responsive+ is a design approach consisting of an aggregate of known techniques, frameworks and best practices that when applied appropriately provides great improvements to maintainability and performance of typical Responsive Design.
The base solution for a Responsive+ approach consists of the following elements:
- Device Classification – a simple way to classify devices as Mobile, Tablet and Desktop on the server-side using a combination of UA and Viewport size
- Server-side Template Framework – to add simple conditional logic to format UI code based on device classification
In the following sections we will break down these steps and illustrate techniques that we use to implement them as well as some reasoning behind the purpose of each step.
Rather than targeting all devices uniquely, the idea is to start out by deriving device classifications to which we would assign devices so that we would be able to deal with them at a broader, feature or form factor level. While yes, there are tons of different devices out there, with more being introduced almost daily, the goal is to organize these devices in a way that we can better address them as they relate to the goals of your given website. For the purposes of this discussion we will use the following taxonomy to relate to devices and their functionalities or form factor:
- Desktop – traditional pc, laptop or desktop
- Mobile – smartphone, iOS, Android, etc
- Tablet – iPads, Android Tablets, and Kindles
- Touch – Devices that support touch events
Here’s a breakdown on how the front-end technologies would work in a Responsive+ developed site that supports the previously discussed taxonomy starting with CSS.
CSS structure for Responsive+
- base.css – normalizer, link colors, font faces.
- phone.css – layout
- tablet.css – layout
- desktop.css – layout
Each file other than base.css contains media queries for that size including portrait/landscape. As new devices demand new layouts, we need to create another file for that device. In essence, we have modularized the CSS based on device (or device classification).
A build script will then bundle these for the target required. For example:
- tablet.min.css = base.css + tablet.css
- phone.min.css = base.css + phone.css
- desktop.min.css = base.css + desktop.css
- full.min.css = a bundled version with all queries intact for device agnostic build
- module.capability.js (for each targeted capability)
UI Build Framework
Optimized and targeted UI payload builds are a critical piece of the Responsive+ approach. For each device classification, only the necessary files are sent down to the client. Server-side build tools such as ANT and R.js scripts, when automated from a build-time event, will minify and concatenate files and their dependencies.
The devices will only receive the css that is required for that classification, negating the need for excessive media-queries and css hacks. Since will are building these css payloads from a set of base files, we can avoid managing multiple forks of the same css.
Device detection is then handled on the server side, allowing for custom tailoring the HTML payload for the targeted device classification. The client-side code already does so much with regards to todays websites, leveraging server-side processing helps to alleviate some of that processing, especially processing that can be handled prior to handing off to the browser. This really helps to optimize the code and helps to insure that site performances is not being neglected.
Device detection is handled through User-Agent parsing and cataloging tools. You can leverage WURFL or dotMobi’s DeviceAtlas to provide cataloged references of devices based on their User-Agent string at runtime. The tool itself doesn’t really matter, rather it’s just the idea that you need to use a tool that is able to provide high level device determination based off of this string. Also it is important that you leverage a tool, rather than bake your own, as you don’t want to have to worry about keeping track of UA mappings, there are too many devices out there for anyone to manage on their own.
While UA sniffing has been seen as bad practice at times, there’s a growing sense that this may not be such a bad thing after all if used responsibly. There are more than a few bright people re-examining this technique as a viable solution, as evidenced by this nearly year-old thread started by Paul Irish and this interesting script, which is being quietly passed around.
The final piece of the high level solution is to leverage a server side templating library that supports basic display logic. This last component really depends on the type of site you are building. If you are building a small, quick and dirty site, you can probably get away with just coding straight PHP, ASP.NET or JSP’s, but for larger scale projects its best to set up an MVC and use something that forces a more strict separation between business logic and view logic. You can select a templating engine based on a technology stack used, for example, Freemarker for Java, Razor for .NET and Smarty for PHP, which makes backend code a lot cleaner and easier to maintain.
Tying It All Together
Serving Right Assets
Serving Up Alternate Content
Sample Header Section using Freemarker for Assembly
<#include "macros/utils.ftl"> <!doctype html> <#if isDesktop()> <!--[if lt IE 9]><html class="no-js lt-ie9" lang="en"><![endif]--> <!--[if IE 9]><html class="no-js ie9" lang="en"><![endif]--> <!--[if IE 10]><!--> <html class="no-js" lang="en"><!--<![endif]--> </#if> <head> <meta charset="utf-8"> <#if isDesktop()> <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9,chrome=1"> </#if> <meta name="description" content=""> <meta name="keywords" content="" /> <meta name="robots" content="noindex, nofollow, noarchive, nosnippet, noodp, noydir, noimageindex" /> <meta name="googlebot" content="noindex, nofollow, noarchive, nosnippet, noodp, noimageindex" /> <#if isMobile() || isTablet()> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" /> </#if> <#if isMobile()> <link rel="stylesheet" href="/css/screen-mobile.min.css" /> <#else> <link rel="stylesheet" href="/css/screen-desktop.min.css" /> </#if>
Credit Where Credit is Due
We are not claiming to have discovered Atlantis. Anders M. Anderson first talked about Responsive Design + Server Side Components, an approach to combine responsive web design with server side components to make advanced responsive web solutions that work for all kinds of devices. What we have done is to streamline this methodology and create an architectural representation that we feel makes the solution scalable, maintainable and easy to implement utilizing any server-side technology.
Wrapping Up – More to Follow
By following this approach we have found that we are able to greatly streamline the overall page size and performance of the sites we are developing. In future articles we’ll break down some examples, including supporting data gathered from sites we’ve worked on. Until then, please feel free to share any experiences you have had with extending Responsive Design to the Server Side, we’d love to compare notes.