Once you are using LiftIgniter, A|B testing design and layout changes is the best way to further optimize performance. 


You can use LiftIgniter's tracking to measure the impact of these changes by identifying a unique "source" value for each variant, similar to the A|B test you probably ran when trying out LiftIgniter against your existing recommendation strategy.


Please let us know if you will be running a test like this by contacting Support - we can add annotations to your account for you regarding the start and end dates of such tests so that you can see them when looking back on the data.


"Source" Names

Typically, you would use our two standard source names, "base" or "LI". "Base" is always indicated by an orange line, while "LI" is always blue. In a design test, where LiftIgniter recommendations are being used in all slices, you can use custom "source" names as well. These will be identified by  purple line in the Analytics graphs. In the example below, the customer chose to test two different layouts for their right-rail widget. Each layout is identified by a different custom source, resulting in two purple lines on the graph. 


In general, we would recommend calling the control slice "base" and use a custom name for the variant so that you can more easily see the performance difference between the two, as one line would be orange and the other purple. 


Full Code Sample

// The template for displaying the recommended items.
<script type="application/mustache" id="recommended-item-template">
  <div class='recommended_item'>
    <a class='headline' href='{{url}}'>{{title}}</a>
  </div>
</script>

// Renders the recommendations and overwrites innerHTML of area marked with 'li-widget-item' according to the template above.
var rendering_callback = function(resp) {
    var els = document.querySelectorAll('#li-recommendation-unit > div.li-widget-item');
    var template = document.querySelector('#recommended-item-template').innerHTML;
  
    for (var i = 0; i < els.length && i < resp.items.length; ++i) {
        // Basically Mustache.render(template, resp.items[i]); 
        els[i].innerHTML = $p('render', template, resp.items[i]);
    }
}

// Tracks each 'li-widget-item' by adding event listener and query string tags to each URL.
var trackAlgo = function(algorithm) {
    $p('track', {
    // marked for replacement during A/B test.
      elements: document.querySelectorAll('#li-recommendation-unit > div.li-widget-item'),
      name: 'my-widget-name',
      source: algorithm,
      _debug: true
    });
}

var abTestHandler = function(slice) {
    // Slice is modulo 100 of the hash.
    // So you can set slice to 0 and 100 to check LI and base slice respectively
    if (slice < 50) {
        // Register call to overwrite widget being tested with LI recommendations,
        // and track metrics appropriately.
        $p('register', {
            max: 4,
            widget: 'my-widget-name',
            callback: function(resp) {
                // You might wish to wrap the code in this callback inside jQuery, to handle load order issues
                //render the recommendations
                rendering_callback(resp);
                // track the recommendation area as the control or 'base' slice.
                trackAlgo('base');
            }
        });
    } else {
        // You might wish to wrap the code in this callback inside jQuery, to handle load order issues
        // track marked areas as the variant name.
        $p('register', {
            max: 4,
            widget: 'my-widget-name',
            callback: function(resp) {
                // You might wish to wrap the code in this callback inside jQuery, to handle load order issues
                //render the recommendations
                rendering_callback(resp);
                // track the recommendation area as the variant slice with a custom source name.
                trackAlgo('new-design-1');
    }
    // Executes all registered calls.
    $p('fetch');
}

// Decide which slice the current user is on.
// $p('userHash') hashes user cookie id to a random 32-bit integer.
// $p('abTestSlice') returns the absolute value of this number mod 100
$p('abTestSlice', {
                 callback: abTestHandler
               }
);