Our tools and workflow for building fast and accessible cross-device web applications
SouthStreet is a set of tools that combine to form the progressive enhancement workflow we use on projects at Filament Group. This workflow is designed to help us deliver modern web experiences that are accessible to the widest range of devices possible.
While we have many open-source projects related to cross-device usability, SouthStreet is focused particularly on the process of delivering enhancements efficiently so that users receive a page that works as soon as possible.
Our SouthStreet workflow utilizes the following tools, all of which are independent Github projects themselves.
- loadCSS: A function for loading CSS asynchronously.
- loadJS: A function for loading JS asynchronously.
- cookie: Get, set, or forget cookies.
- criticalCSS: A command-line tool for extracting critical CSS for a page. (we use this with grunt-criticalCSS)
- Grunticon: A grunt-based tool to make it easy to use SVG graphics with fallbacks for older browsers.
- AjaxInclude: a plugin that is designed for modular content construction, that runs on jQuery (or our Shoestring DOM utility)
- Picturefill: A responsive images polyfill.
Together these tools form the core of Filament Group's progressive enhancement workflow. The scope of these individual projects vary widely, but they all share a common goal of serving front-end code faster, either by preventing or deferring the loading of code and assets that are not essential to the device, or by offering light-weight alternatives to common patterns.
For demonstration purposes, the Demo page of this repository contains a working example of these tools working together.
Please note that while these tools do represent key components of our overall approach, their applicability to a particular project always varies, and these particular projects are not always the best tool for the job at hand. Depending on whether a particular tool makes sense for the problem we're solving, we will often use alternative tools that provide similar functionality instead. For example, we commonly use jQuery instead of Shoestring (below), as Shoestring provides a small subset of jQuery's featureset, and is not always appropriate for the needs of our projects. In essence, the projects in SouthStreet are developed with a goal of ease of use and compatibility, but they should always be evaluated against other potential solutions.
Let's break down the role that each one plays.
Initial Page Load Tools
The following SouthStreet tools are used in the initial page load step.
Typically, a site that uses Enhance will start by including
enhance.js directly in the
head of the page -inline, not an external reference. Within
enhance.js, the following steps are often taken:
- Define some variables and functions for loading assets and accessing information about the browser and markup
- Run one or more tests to see if a browser is qualified to load and render additional enhancements
- A. If it's not qualified, exit early and do nothing more
- B. If it is qualified, proceed on to load additional assets, add classes to the document, etc.
enhance.js file in this repository.
Critical CSS is a task we typically run during a build process. We use the task to evaluate every unique template in a site to determine the subset of styles in a site's CSS that are necessary to render the top portion of the page. As these styles are determined, we write them to files that are intended to be included directly in the
head of each template, on the server-side. Inlining only these most critical of styles allows us to avoid making render-blocking requests from the
head of the page, which dramatically increase the time it takes for a page to be usable. Once included in a template, we use EnhanceJS to request the rest of the site's CSS in a single request, and to set a cookie that tells the server on subsequent visits that the full CSS file is most likely cached now and can be referenced from the head of the page (instead of inline styles).
Inlining CSS this way is designed to optimize the first visit to any page on a site, aiming to render a usable page in less than a second on a modern connection. It follows the recommendations from Google's Pagespeed Insights. Check out our own site's score on PSI to see how well it works in action.
For examples of how we recommend configuring the
head of a page to use EnhanceJS and CriticalCSS together, check out the EnhanceJS readme, or explore the demo files in this project.
Grunticon is a Grunt-based tool to make it easy to use SVG graphics with fallbacks for older browsers. We run Grunticon alongside our other build-time tasks to create CSS files that include our icons, which we then load asynchronously using Grunticon’s generated loader script, or by using our own scripts like
The following SouthStreet scripts are typically loaded in a qualified manner by EnhanceJS, after bundling them in a single file amongst any other scripts we may need. These are part of SouthStreet purely because they serve the purpose of facilitating further enhancements to a page (by fetching assets conditionally).
AjaxInclude works by referencing external fragments of HTML content via HTML5 data attributes. For example:
<a href="articles/latest/" data-before="articles/latest/fragment">Latest Articles</a>
In this case, we have an ordinary link to external content, which is essential for accessibility across all devices, but the link is also tagged with a
data-before attribute that references a URL that contains a fragment of that external content to pull into the page. The AjaxInclude plugin will see this and include that content before the link.
You can add these attributes to elements in your page anywhere non-essential fragments of content can be included from an external URL. jQuery-api-like qualifiers like
data-replace are all supported. Also, the
data-threshold attr allows a min width for this to apply.
Note: these attributes can be placed on any element, not just anchors. You might find
data-append to be most useful on container elements.
Once the DOM is ready, you can apply the plugin like this:
Picturefill, while listed last in the SouthStreet lineup is one of the most critical pieces of all with regards to delivery optimization. Picturefill allows us to reference several sources for a particular image in an HTML document, and based on which source's media query matches, Picturefill will load only one image appropriate to that context (and reevaluate whenever the viewport dimensions change as well).
You can find more projects at our website as well. Filament Group, Inc