Thursday, 28 November 2013

Optimising web site performance with page speed

If you haven't measured the performance of your web pages, then you MUST and given that it's so easy to measure and improve then it's criminal if you don't.

You can measure performance in most browsers, however let's look at you can do it with chrome - note that firefox usage is pretty similar if you install the pagespeed addon.
  1. Open you page in chrome browser.
  2. Click menu view / developer / developer tools.
  3. Click on the Audit tab in the developer tools window.
  4. Click Run.
  5. Step through each of the audit report items in turn and address the significant ones you can.
Depending on your web server you use, you may be interested in modpagespeed (Apache), ngx_pagespeed (Nginx) or IISpagespeed (IIS - not personally verified) to help address some the items reported in the page speed audit.

Typical items you may want to address from the report include
  • Resource caching - resources (images / CSS / JS) don't tend change much, so it's good to implement an appropriate cache policy by setting appropriate HTTP headers.
  • Enable GZIP compression - most browsers, devices now support GZIP compression.  Compressing content to be sent over HTTP, even with the overhead of compression and decompression on server and client side,  so this is often valuable optimisation.
  • Optimise images - large high resolutions images can be quite a significant part of the pay load.  Sometime these can be compressed without loss, sometimes you may want to reduce the size for smaller screens.
  • Defer parsing of JavaScript - you want your page to display as soon as possible.  One thing that can slow down the displaying of the page is download and execution of JavaScript IF you've coded the site in a less than optimal way - read how to improve you JavaScript loading.
With any of these changes ideally you'd follow a test driven approach - observe the problem, measure the improvement of the fix and include such verification in test scripts so you have ongoing monitoring the optimisations.   Try not to make blind changes in the hope that performance is improved, since you don't want to make change that make insignificant changes (or even worse) have an adverse effect.

Tuesday, 26 November 2013

Semantic HTML, CSS Classes, JS Selectors and all that

This is blog I wrote a few years ago. I thought it'd be useful to republish it here as it's an excellent starting ground for creating semantic markup that can be rendered well across all devices.

If you write any HTML, then you'll soon realise that careful choice of HTML elements and class namings will reap many a reward. The HTML document you create '''is an interface''', an interface that is not only read by a browser to render your page to the user's screen, but also the interface in which:

  • JavaScript can traverse, interact with the page and extract content to post back to the servers (AJAX).
  • Drive automated & scripted web test tools - Geb (and spock), Selenium
  • Third parties can access content from the page and re-purpose on other web sites.

A well chosen interface will allow your HTML code to stand the test of time, be picked up and maintained by others, drive increasingly interactive JavaScript driven experiences and survive site redesigns. Below are listed a few key drivers which I follow.

Readability

Write Classes with Meaning, a.k.a Semantic HTML

Plain Old Semantic HTML (POSH) gives us the POSH check list and helps drive some semantic HTML that I create.

  • The first rule of POSH is that you must validate your POSH.
  • Second, drop the use of TABLEs for purely presentation purposes, spacer GIFs, and presentation HTML in general.
  • Next, fix your Bed and BReakfast markup.
  • Eliminate Anorexic Anchors.
  • Re-use pre-existing posh-patterns.
  • Use good semantic class names.
    • Choose naming that gives meaning, not naming that indicates presentation, for example, "indent", "red" and "bottom-margin" are bad choices.

Define classes for reuse and allow context selection

Use

<div class="event"> 
  <div class="time">18:00</div> 
</div> 

instead of

<div class="event">
  <div class="eventTime">18:00</div>
</div>

since this allows the class time to be used in other contexts to identify times of different items, but still allows you to pick out the event time with .event .time

Avoid Obtuse Acronyms and Word Shortenings

The following :

.checkbox.email.selected { ...} 
.address {...}

are better than

.cbem.sel { ...}
.addr {...}

The extra characters saved by shortening the words does not make the pain for reading of code by third parties worthwhile. And, anyhow, downstream automatic optimisers could always deal with minification if it was worth while. Don't let the goal for keeping pay load to a minimum, lead to unreadability.

Reliability

Don't make your selector rules too specific

Be careful of using too much specificity in a CSS selector rule, e.g.

.events ul .event .time { ... }

Today, you may have

<section class="events">
  <ul>
    <li class="event">
      <div class="time">18:00</div>
    </li>
  </ul>
</section>

but you may move it out to a ol our out of a list tomorrow. Only use the ul in selector if you only wanted to apply the rule if it was in a <ul>. Also in the runtime stack this ul might be adapted to alternative elements on another, perhaps legacy, device - so locking the style selector unnecessarily to the <ul> could have an adverse affect on alternative renderings of the site.

The dangers of relative traversal to locate items in the DOM

Be careful with locating an element through relative traversing APIs, like parent(), prev() and next()

$(this).parents().parent().prev().show();

If you move an element slightly this logic might mis-fire. Consider locking down the rule a little, e.g.

$(this).parents(".event").find(".time").show(); 

i.e. go up to find the ancestor with class event and then within that find the element with class set to time. This second approach is more robust to HTML shuffles.

For example you may have a display control that displays a content item, but also provides an edit button update the content item. You might toggle between the display and update controls as follows:

// Click edit 
$(".event .action.edit").click(function () {
  $(this).parents(".event").find(".read-control").hide();
  $(this).parents(".event").find(".update-control").show();
}); 
// Click save
$(".event .action.save").click(function () {
  saveEvent();
  $(this).parents(".event").find(".update-control").hide();
  $(this).parents(".event").find(".read-control").show();
});

IDs vs classes

ids must be unique in a complete HTML page, so ensure that it is. Don't use an id on an element that is likely to be repeated or reused across a page, e.g. a date control. If in doubt, then you probably should be using a class.

Allowing The Browser to Render The Page More Efficiently

The way you write your selectors can have an adverse effect on how efficiently a browser can render your site.

Further Reading

Tuesday, 12 November 2013

Context is More Than Device ... Perhaps it's About Socks

The SDL Context Engine was born from technology that made a lot of head way in creating web sites that adapted to the device capabilities where we would enhance responsive web design techniques with server side optimisation.

However, the philosophy has always been about contextual experiences way beyond adjustments based on the screen. SDL provides a whole suite of technologies that put a lot of contextual, or ambient, information sources at our finger tips. The Tridion Ambient Data Framework (ADF) has been taking advantage of this for some time.

Let's start with one of our team architectural definitions.

Ambient information is information that is observed from the continuous interactions between users and applications, along with a devices that the users use to interact. This includes:
  • Customer analytic information.
  • Content item properties consumed by users, and associated content metadata.
  • Device capabilities.
  • Contextual properties that are selected from a context repository.
  • Information from users interactions with social networks.
Such information can help web interactions between you and your customer to be tailored based on who they are, how they are communicating and the user's intent, just like the conversations between a local shop keeper and their loyal local people can be quite different to conversations with newcomers (VIDEO).

The Context Engine Vocabulary is a strongly typed definition of the language of this contextual information. This vocabulary is grouped together into aspects of the context, such as device, browser, os, user, ui.

Some properties that we provide are :

AspectPropertyType
browserdisplayHeightInteger
browserdisplayWidthInteger
browservendorString
browserversionVersion
devicevendorString
deviceversionVersion
osvendorString
osversionVersion

The vocabulary can be extended way beyond the set of device, browser and os aspects that we provide. So you may decide to extend this vocabulary, for example :
AspectPropertyType
userlikesSet
This vocabulary forms the foundation of the language that we interact with such that may deliver targeted content to a user based on their known desires. Perhaps you'll see something like this in one of your Tridion templates.
<tcdl:if expr="user.likes.contains['socks']">
  Show socks
</tcdl:if>

Monday, 11 November 2013

The Value Of Context

A customer does not arrive at your website by chance. Each customer has followed links, clicked on banners, entered in search text, responded to questions and they have now entered your site on a particular device looking for something.

You've got a few seconds to respond before they look somewhere else.

In these few seconds you've got an opportunity to present the user with an experience that captures the user's attention and satisfies their needs. You want their experience to be fulfilling, for example the customer gets information they need, signs up to your service or buys something. You also want them to come back again and again and tell others about what a great service you provided.

To fully reach your potential you need to first be aware of the context of the user.

  • What device are they connecting on? - mobile, small screen, touch screen.
  • Where have they come from? - search terms they entered, banner they clicked on.
  • Where are they? - which country, which city, which street.
  • Do you already know anything about the user? - anonymous vs returning customer.

With each of these contextual properties you have the opportunity to improve the user experience and delivery are more relevant experience quicker.

I’m proud to be part of the SDL team who are creating the technology that brings you the power of context and lets you enrich your web experience for each and everyone one of your users. Via this blog I'll be sharing with you my experience on delivering contextually optimised web experiences and show you how you can use SDL technologies to achieve this.