An Event Apart: Responsive and Responsible

by Luke Wroblewski February 18, 2013

In his presentation at An Event Apart in Atlanta 2013 Scott Jehl outlined a number of ways to build responsive Web sites that take performance in account. Here's my notes from his talk: Responsive and Responsible.

  • Responsive design is just part of building a responsible design. We need to consider a number of factors beyond the layout: performance, behavior, accessibility, and costs.
  • Building Web products to be universally accessible requires empathy. We have to walk in people’s shoes. This includes a lot more than just people with disabilities – it includes slow network connections, less capable devices, and more.

What Causes Poor Performance?

  • Most of poor performance is our fault: the average page in 2012 weighs over a megabyte. Much of this weight comes form blocking assets like Javascript and CSS that prevent the page from being displayed.
  • The average size of images on a Web page is 788KB. That’s a lot to send down to mobile devices.
  • Javascript, on average, is 211KB per transfer. This comes from the libraries and code we choose to include from third party networks. This cost is always transferred to our users. We need to stop building things for developer convenience and instead build them for user experience.
  • 86% of responsive designs send the same assets to all devices.

Content Parity, Optimized Experience

  • We want to deliver content based on our user’s needs. Only a few users ago we were locked into normalizing things across a number of browsers. Today the diversity of devices makes this idea seem ridiculous. Instead we want to optimize for different devices.
  • Content parity does not mean every experience is identical. Every browser that comes to our Web site is unique. We need to code in a way that doesn’t presume too much about: viewport size, orientation, font size, settings, preferences, and input modes.
  • Being responsive from a layout perspective doesn’t preclude being responsive form a performance perspective.

Delivering Content

  • To load content from a Website, a client makes a request, DNS sends it to the right host, and the host replies with the requested assets
  • On mobile devices, we go to a tower first, then to a DNS, then a host to get content. The connection to the tower takes two seconds and is totally out of our hands. That delay only happens once and then we can send files back and forth after the initial connection is made.
  • From there we load HTML and any referenced files when all blocking files have been received. Be careful of what you include in blocking requests.
  • After 8 seconds, the carrier will cut off a connection so we want to load as much as possible when that initial connection is open.
  • Every http request we make is a bit of a gamble -it can fail. So we don’t want to gamble too much with many requests -especially if they are blocking.

Delivering HTML

  • Tiered delivery: if a piece of content is already accessible somewhere else, you might consider loading it lazily.
  • For example: home pages are navigation tools. They mostly include links to other parts of the site.These kinds of pages are prime for deferred loading.
  • In the initial load, we could just include the critical links in the source then use Javascript to load additional content (like samples of what’s behind that link) after the initial page downloads.
  • We can enhance the content itself using a technique called Ajax-include. We start with a simple URL and add a data attribute that references an HTML fragment to the link’s mark-up. When Javascript is executed, the link will be replaced with a full set of content using Ajax.
  • To do this, consider using a data attribute on a link like “data-after”.
  • You could take this deferred loading further and only show the additional content if a certain media query condition is met.

Delivering CSS

  • CSS is a blocking element: browsers wait until it is all loaded before displaying a page. This prevents un-styled content from showing up.
  • Of all front-end content, CSS is the hardest to manage the transfer of.
  • Mobile-first media queries: start with CSS that is wide open. Assume no media queries are present. Then adjust using min-width media queries.
  • Mobile-first media queries deliver a broadly usable default. These initial styles go to all browsers but it sometimes you might want to use a @media only all qualifier to target all browsers that support media queries. This is a good way to qualify more advanced styles.
  • But with this approach, we are sending all our CSS files to all browsers even if they’ll never use them.
  • Every browser downloads every CSS asset today –whether it needs it or not. While we want style sheets to be there when we need them, we don’t necessarily want them to be blocking page rendering.
  • Webkit does a little better, it loads media queries that apply and renders those on screen. However it still downloads all CSS files regardless of whether they can be used on the device or not.
  • The best approach for CSS is still to combine all your CSS in one file. But minify and gzip it. CSS compresses well. GZIP finds repeating segments and reduces CSS file size substantially.

Delivering Images

  • Images are 62% of file size on Web pages.
  • Images don’t block page rendering but they can negatively impact page size and data plans.
  • Background images can be managed with media query cascades to only be loaded when needed. Foreground images are another story.
  • Compressive images: the quality of a jpg influences its files size more than its pixel dimensions.
  • The memory footprint of a very large image might cause performance issues on a low-powered device but there’s no evidence that is a big issue.
  • Responsive images: two proposals have made their way into the standards process: picture and srcset.
  • The picture element works like the video element in HTML. It has a number of media query-qualified images to load based on what each browser can support and a standard image for fallback when none of those attributes are true.
  • Srcset is an attribute that you add to an image element. Its very good at managing pixel densities through attributes like 2x, 3x. The browser has the last say on which image to load.
  • Media queries, as used in the picture element, don’t defer to the browser.
  • Picturefill is a Javascript polyfill that brings similar support to a DIV-based solution. This prevents pre-fetching images that are not needed.
  • Should we load retina images for devices that can use them or should we give people a choice of what kind of image they want? After all, serving retina images by default really increases download size.
  • The picturefill solution can be used to load a standard definition image by default and then give people the option to load a high-resolution image if they choose on their retina device.
  • Managing images for all the different resolutions is getting harder and harder. Instead of using raster images for icons and background, we could use vector art using SVG.
  • SVG is text it compresses very well because it is just mark-up. Referencing SVG inline is relatively easy. Browsers that support SVG load it easily but those that don’t can be supported with an onerror attribute to load a fallback image.
  • Grunticon is a tool that listens to a directory of SVG files, updates a CSS file that encodes all those files as data URIs as CSS classes, which can then be concatenated with other CSS files.

Delivering Javascript

  • Javascript is the second largest part of our pages and it blocks page rendering until loaded.
  • Start by loading the smallest amount of Javascript you can. Use it to determine what to load next. Initial Javascript: load feature tests, essential polyfills, asset loader, and a script loader.
  • If a device is qualified, you can add the Javascript you’ll need everywhere and specific files based on what each device can use. How to determine what Javascript to load: broad qualification, browser features, device/environmental conditions, or template types.
  • You can load some CSS with Javascript as long as it is not required for default presentation. Additional fonts or background images are good candidates for Javascript loaded CSS.
  • Third party widgets (to embed on your site) should be loaded asynchronously. But support for async is not perfect as it is only supported in Internet Explorer 10+
  • Defend the critical path to loading key content for your pages.
  • We have the tools to create rich experience without excluding people. But we need to work responsibly to do so.