Rails Plugin for Google Website Optimizer for AB Tests – Dynamic Content Experiments and No Flickering!

TL;DR: If you don’t care how this plugin works and just want to see/get the code, it’s available at github: http://github.com/tpunder/gwo

There’s a ton of reasons to reasons to invest in conversion rate increases.  If you’re spending $1 to acquire 10 visits, and you can get 2 instead of 1 to convert its like putting an extra dollar in your pocket.  A couple days ago Rand Fishkin from SEOMoz even said “2010 is the Year of Conversion Rate Optimization

Google Website Optimizer’s Homepage will give you a number of reasons to use their product My biggest reasons is its FREE!

Last March, we met with Eric Vasilik with the Google Website Optimizer Team in the Seattle Google Office about some hang-ups we had trying to A/B Test functionality and integrate Google Website Optimizer:

  1. Speed. The out-of-the-box Google Website Optimizer code does something like this:
    1. Download/Initialize GWO Code
    2. Identify which experiment/treatment group the user should see
    3. Download each of the content sections that should change and
    4. Use javascript to dynamically update each of the content sections of the page (FLICKER!)
  2. Static Content. Since you must store the HTML fragments in GWO for the service to return back the appropriate multivariate combination to show to users, the HTML fragments must be static.
  3. Maintenance. This ties back to our #2 reason, we would have to upload each of the HTML fragments into the GWO tool so they could be tested.  Since we have to code them locally to make sure they function & display correctly anyhow, it effectively means we need to duplicate the code to GWO.

The solution?  Leveraging a few very very clever Javascript/HTML tricks this is what we’re doing for our Auto Parts Price Comparison site.

Background:

A vanilla GWO Implementation operates similar to:

GWO-Basic1

Tricked out solution looks like:

GWO-Advanced

Why is it clever?  Lets walk through each of the scenarios for the GWO Variations.

Scenario 1: No Javascript Support

<!– Section1 – Default content –>
<script>
var GWO_Section1 = utmx(“variation_number”, “Section1″);
if (GWO_Section1 != undefined && GWO_Section1 != 0) document.write(‘<no’ + ‘script>’);
</script>
Default content – shown by default<br>
</noscript>

Browser ignores everything inside <script> tags and ignores the </noscript>

<!– Section1 – Variation 1 –>
<script>
if (GWO_Section1 == 1) document.write(‘</noscript a=”‘);
</script><!–”>
Alternative content 1<br>
<script>document.write(‘<’+’!’+’-’+’-’)</script>–>

<!– Section1 – Variation 2 –>
<script>
if (GWO_Section1 == 2) document.write(‘</noscript a=”‘);
</script><!–”>
Alternative content 2<br>
<script>document.write(‘<’+’!’+’-’+’-’)</script>–>

Scenario 2: Browser Supports Javascript – Variation == Control/Default Treatment

<!– Section1 – Default content –>
<script>
var GWO_Section1 = utmx(“variation_number”, “Section1″);
if (GWO_Section1 != undefined && GWO_Section1 != 0) document.write(‘<no’ + ‘script>’);
</script>
Default content – shown by default<br>
</noscript>

Browser evaluates GWO_Section == 0 so the document.write(<noscript>) is NOT executed resulting HTML code is:

Default content – shown by default<br>
</noscript>

Browser ignores the </noscript>

<!– Section1 – Variation 1 –>
<script>
if (GWO_Section1 == 1) document.write(‘</noscript a=”‘);
</script><!–”>
Alternative content 1<br>
<script>document.write(‘<’+’!’+’-’+’-’)</script>–>

Since GWO_Section == 0, the document.write(‘</noscript is not executed, but however the 2nd <script>document.write IS still executed resulting in

<!–”>
Alternative content 1<br>
<!–</script>–>

The HTML comment starts with the first <!– and keeps going until –> hits (the browser doesn’t even try to interpret the DOM inside the HTML comment – making this the most efficient way to “throw away” code from even being parsed by the HTML engine.  The variation 1 never gets displayed.

Scenario 3: Browser Supports Javascript – Variation == Experiment Treatment

<!– Section1 – Default content –>
<script>
var GWO_Section1 = utmx(“variation_number”, “Section1″);
if (GWO_Section1 != undefined && GWO_Section1 != 0) document.write(‘<no’ + ‘script>’);
</script>
Default content – shown by default<br>
</noscript>

Browser evaluates GWO_Section1 == 1 so it DOES print the <noscript> resulting in:

<noscript>
Default content – show by default<br>
</noscript>

Browser starts at the first <noscript> and ignores everything until the ending </noscript> – thereby ignoring the control treatment’s HTML

<!– Section1 – Variation 1 –>
<script>
if (GWO_Section1 == 1) document.write(‘</noscript a=”‘);
</script><!–”>
Alternative content 1<br>
<script>document.write(‘<’+’!’+’-’+’-’)</script>–>

GWO_Section1 evaluates to == 1 and the document.write prints out resulting in:

</noscript a=”
<!–”>
Alternative content 1<br>
<!–</script>–>

There’s two clever things in this one. The first is the a=” starts to create an HTML attribute that “ingests” the dangling <!–. The second, is the <!–</script>–> is a complete HTML comment, so there isn’t a dangling </script> tag floating in the HTML. Poof the Web Browser is now showing the Treatment HTML.

After we met with Eric he posted a link and an explanation for this trick at http://www.gwotricks.com/2009/05/server-side-dynamic-section-variations.html

Editor’s Note: The original link above is currently dead, I’ve reposted the original article for reference at: https://startupmonkeys.com/2009/05/01/server-side-dynamic-section-variations/

We have a Rails Plugin that encapsulates all of this logic pretty well – so you don’t have to worry about all of the javascript hacks:

http://github.com/tpunder/gwo

Happy A/B + Multivariate Testing!

Advertisements

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