Green Boilerplate advances – Part I


This is an update on my current work with Green Boilerplate (GBP) http://greenboilerplate.com, a project to develop a “sustainable boilerplate.”

The project fits into the larger context of  boilerplates out there (e.g. blueprintcss, Twitter Bootstrap and html5 boilerplate) but takes sustainability, rather than development, as its primary focus.

Purpose

The goal of this boilerplate is to help designers that don’t have large staff or site engineers optimize for sustainability, rather focus on individual areas like energy efficiency, usability, accessiblity, etc. Sustainability is a better “big” goal than optimizing features of the system, since it also takes into account UX and the larger Internet the site is embedded in.

GBP is designed for smaller design groups and freelancers who are not hardcore WPO experts. One potential target for Green Boilerplate is small business, like that championed by the Web Standards Project (of Acid1, Acid2, and Acid3 fame) a few years ago:

http://www.webstandards.org/action/smb/

Another target is freelance developers, many of them building sites for smaller clients, and employing outmoded and inefficient methods to do so.

A final group is web designers with modest programming skills. During the recent rise of “good” JavaScript, lots of great solutions to website design have appeared. However, someone good at HTML and CSS without JavaScript might have difficulty including them in their projects. GBP is a way that useful WPO and other sustainability options can be put into modest projects.

These sites are often build using canned templates (with horrible footprints) or by web designers who haven’t kept up with the times and are still coding like it is 2003. GBP offers an alternative route to “pretty good sustainability” for these groups.

Principles

Green Boilerplate follows the core principles of Web Sustainability, adapted from other design disciplines:

General Sustainability Principle Sustainable Web Design Goals
Make meaningful products Make websites that are have real value, not fashion or tech-tricks
Easy design rollback Iterative or Agile design workflow
Source Renewable Materials  Switch to a “Green” webhost
Design products to work in the future  Implement classic design strategies
Design with the user in mind  Create effective User Experience (UX)
Ensure democratic access  Build accessible, responsive websites that work on all browsers
Interchangable Parts Apply standards-based design
Minimize energy and resource consumption Web Performance Optimization (WPO)
Don’t corrupt the virtual system  Search Engine Optimization (SEO)

Features

To implement general sustainability, GBP extends several ideas in common use on the web

  • A standard “boilerplate” structure that can be used as the basis of new projects
  • A “configurator” allowing the
  • Progressive Enhancement, using server-side code to provide functionality to the “browser-challenged”
  • Client-side feature “sniffing” similar to Modernizr.

To these features, standard in many boilerplates, we add

  • Support for “hybrid” designer-developers, as opposed to siloed designers and programmers
  • WPO support for groups without a WPO specialist or site engineer
  • Installation simple enough for the typical web designer to use. The cutoff point is whether you have to open the terminal window to make the boilerplate work. If you do, the boilerplate will be too hard to use by the majority of web designers and some front-end developers.
  • The boilerplate provides support down to DOM0 browser JavaScript. Reference points include Opera 5 and Navigator 4.8, developed before DOM1 standards were fully implemented around 2000. This also allows the boilerplate to support the first era of mobile web browsers with very basic JavaScript support.
  • Server-side user-agents are analyzed via HTTP header sniffing, to determine browser features before the page is downloaded to the client
  • User agents are scanned against simple PHP-derived databases, which don’t require SQL database installations or complex solutions like WURFL.
  • Client-server communication is included in page templates, to turn feature detection off when it isn’t needed anymore
  • Server-side variable sniffing is combined with user-provided data to rank the ISP in terms of bandwidth.
  • ISP sustainability ranked using information from the Internet Index.
  • User-centric response to changes in content, similar to, to minimize re-download of information.
  • Carbon footprint calculations based on client and server data

In this first installment I describe some specific technical features allowing Green Boilerplate uses. Later postings will detail how non-feature detection is added to the list of relevant properties, leading to a rough calculation of carbon footprints and overall sustainability.

PHP-based database

Many web apps use a combo of server-side code with databases, e.g. the “classic” LAMP of PHP and MySQL. The problem with these approaches is that many web designers don’t know enough to easily install and configure a database. This problem can be reduced if we go all the way to an integrated Content Management System, or CMS, but this is something to avoid – we want to keep things simple, like other boilerplates. This is also the reason for using PHP – unlike Python or Ruby, it’s universal on the meanest of web hosts.

Therefore, GBP uses a PHP-only database for server-side processing. The database consists of files containing standard, un-serialized PHP arrays with browsers, versions, and features supported. Using basic PHP files makes installs very easy – an unzipped directory just has to be uploaded in one step to the webhost.

For security, the PHP database is read-only, and .ini files are not used. More elaborate schemes require greater understanding of server-side security on the part of the designer working with the boilerplate, so they’re avoided.

A database of this kind isn’t readily configurable. Instead of pushing configuration to the designer side, GBP provides a “configurator” for getting upgrades to the database.

Server-side feature detection

During recent years, there has been a shift to “heavy” front-end web apps with lots of HTML/CSS and JavaScript providing user interface and interactivity. This is a shift from the 1990s, when limited browser features required that much of a website’s functionality be put on the server-side.

Green Boilerplate seeks a medium. IMHO, current client-side feature detection is too expensive. Support requires loading lots of JavaScript polyfills, which, due to the slow speed of older JavaScript implementations, really weighs down older browsers.

One of the reasons that server-side detection has been avoided is the problem of inference. In the past, server-side solutions often broke due to reasoning like the following:

If user-agent has “MSIE” than send MSIE-specific code.

The problem is that browsers often lie. The other problem is that the nature of MSIE may change over time. In the past, a “MSIE” in your user-agent meant that the browser had the problems of IE6-IE8. But today, we have the awesome IE10, a web browser so good that I prefer it to Chrome on Windows 8. Inferring inferior performance due to a “MSIE” in the user-agent string will ultimately fail.

However, we can avoid this problem is we keep server-side detection limited to “fossil” web browsers that have standardized and will not change. “MSIE” will change, but “MSIE 6.0” will not. In this case, it is OK to infer features from a keyword in the user-agent.

In addition, capabilities of fossil web browers don’t expand over time. True, someday, IE10 will be old, but the timeframe will be obvious. In other words, if we know the release date of a browser, we can go a long way to defining its features, and be confident they won’t suddenly change. Knowing a browser is from 1998 allows us to safely infer that it does not support HTML5.

Therefore, most of the sniffing done on the server-side by GBP looks for old browsers. In contrast to a typical browser-sniffer (which obsesses at figuring out which version of Chrome you have), GBP looks for only the bad old stuff, e.g. Firefox 2.

If a browser isn’t recognized, it is passed through and most feature detection therefore on the client.

This approach isn’t not a good as the exhaustive user-agent scans performed by WURFL and related commercial solutions. GBP isn’t aimed at these groups, which are likely to be large enough to employ site engineers and WPO specialists to optimize server-side performance.

Progressive database loading

When conducting a user-agent scan on the server-side, PHP databases are loaded according to the likelihood that a given browser will be found. This is set up in the “configurator” boilerplate. At present, this means desktops and a few common mobiles. If the browser isn’t found, more PHP databases with less common browsers are loaded using the require() statement in PHP.

Server-side variables

GBP also attempts to sniff variables related to the server. The most obvious one is the domain name, which can help in figuring out the sustainability of the system via databases like The Internet Index.

Server-side geolocation

One of the variables that GBP optinally can be configured for is to get geolocation data for the server. GBP has “hooks” into several free server-side APIs providng some geolocation support.

Why geolocation? It is relevant to sustainability because, just like food, “buying local” is preferred to buying a remote hosting service. For example, AISO.NET is one of the “greenest” ISPs in the world – but many services selling “green” hosting in Europe are actually buying their hosting from AISO.NET. This means that, for the intended audience, each connection is jumping through dozens of routers and networks. Is this really a “green” website?

PHP builds the GBP JavaScript object

The JavaScript object corresponding to GBP is created by the server-side PHP. By default, the object has “undefined” for all the features it detects in the browser, server, and other variables. Some of these variables are filled in by server-side sniffing prior to download.

echo 'var GBP = GBP || (function ()
this.hasHTML5 = undefined;
this.hasCHTML = undefined;

'; //PHP code

We use “undefined” here, instead of a NULL since we don’t have the property defined. If we test and fail, a null result would make sense, but the initial GBP object has all its properties undefined.

Note that the final GBP object is quite simple, without functions or sub-objects. This is because the functions replace themselves with their results, as shown below:

var GBP {
...

function isCanvasSupported() {
          var elem = document.createElement('canvas');  
         this.isCanvasSupported = !!(elem.getContext && elem.getContext('2d');
      }
};

If a feature can not be inferred on the server, the PHP code constructing the GBP object attaches a client-side function for checking for the feature on the web browser.

echo 'this.hasHTML5 = true,
this.hasBlobs = function () {
if (typeof Blob !== "undefined") {
  // use the Blob constructor
} else if (window.MSBlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder) {
  // use the supported vendor-prefixed BlobBuilder
} else {
  // neither Blob constructor nor BlobBuilder is supported
  }
},
this.hasCHTML = false
'; //PHP code

In some cases, server-side sniffing will infer an browser that doesn’t support DOM1 level JavaScript. In this case, the GBP object is written on the server, but assembled dynamically on the browser, instead of with a JavaScript literal object. This seems to work better with very old browsers (e.g. older editions of Opera).

var GBP = new Object();
GBP.hasCHTML = false;
GBP.hasHTML5 = true;

Cached features

Current practice with libraries like Modernizr lets feature detection happen over and over agai,n as subsequent pages are loaded on a site. GBP avoids that by writing a local copy of the information the first time it runs, using HTML5 local storage, with a fallback to HTML cookies if necessary. Each time the GBP script starts, JavaScript checks for stored information, and avoids new rounds of feature detection if GBP data is already present.

Signaling the server

By itself, local storage wouldn’t turn off server-side user-agent sniffing or GBP construction on the server in PHP. To shut database searches off after feature detection is done, GBP writes a small cookie to output. The next time a page on the site loads, at the start of the PHP script, this cookie is checked for, and if present, feature detection using the user-agent on the server does not occur.

If cookies are disabled, no message goes to the server, and every page triggers a redundant server-side re-creation of GBP. While a problem, this is similar to current methods, and will only happen for a small number of users.

At present, cookies are used for this client-server communication. Ajax is out, since many older browsers we want to support might not handle an XMLHttpRequest correctly. However, in the future it might make sense to use some of the other, non-cookie methods employed by evercookie (http://samy.pl/evercookie/). Cookies are public, and non-cookie methods are sometimes used without the user’s knowledge. If alternate storage methods are added to GBP later, they will need to be obvious and public, with a method allowing it to be turned off by the user. It is also important not to expand the size of the HTTP header that cookies and other chunks of information travel in, since HTTP requests are the most energy and resource-intensive thing a site can do.

The GBP sequence

The following features lead to these steps when GBP is invoked:

  1. First round of server-side feature detection with server variables and a user-agent, a GBP JavaScript object is written to output.
  2. GBP checks for unknown features with supplied objects, and writes to local storage (cookie or HTML5).
  3. GBP writes a small “reply” cookie. The next time a web page is requested, the cookie moves to the web server.
  4. If the cookie is present, no server-side feature detection occurs, and the GBP object is restored on the client from local storage.

These steps achieve the goal of minimizing both client and server-side CPU cycles, as well as reducing the amount of data sent through the network. This is especially true for HTML systems with true local storage.

On old browsers, the entire GBP object will be echoed back to the server. This is less efficient, but since GBP creates a relatively small JavaScript object, the penalty is small. In development mode, this potentially allows for the server to record the results of client-side feature detection for a given user-agent. This allows progressive refinement of the GBP database. In the final form, it may be useful to allow this information to be reported, but it will be turned off by default.

This concludes Part I of GBP. In the second part, we’ll detail how non-browser features (like the Internet Index of a webhost) can be integrated into GBP to move it from WPO to true sustainability.

2 Comments

  1. Thanks Tim, I’ve pinged via your contact form. Yup, I’m not fully ready to set up testing, so I’ve left the form off the GBP site. However, contacting me at pindiespace@gmail.com is fine. I’ll be looking for some VERY ALPHA testers in a few weeks – feel free to check in and sign up.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s