I know you’re all working hard, but it’s time to take a quick break and lighten up.  Last year, we sent our core analytics JavaScript file off to boot camp and it’s returned faster, lighter, and more powerful.  The updated core file was released as part of the May maintenance release (5.23.2013) along with a re-vamped code manager page.

The new version is light & fast enough to be used with mobile sites AND robust enough to be used on the full desktop web, allowing you to leverage a single JS file across all web measurement environments.  There are also a number of powerful new capabilities in the new JS file which I’ll walk you through in detail; but first, let’s hit the highlights:

  • Smaller: 22k uncompressed & 8k gzipped (H.26 code is 33k uncompressed & 13k gzipped)
  • Faster: 3-7x faster than the H.25 code
  • Native Utilities: new native utilities provide product-level support for several common plugin use cases (getqueryparam, linkhandler, cookie handling, url encoding)
  • Modules: updated Integrate and Media Modules available from code manager
  • Head Tag Deployments: deploying s_code and page code inside the <head> tags is fully supported

A Quick Word About Performance

Before you run off and set up a performance test to see if the improvements are really as good as we say they are, the image below shows the results of our QA testing using JSLitmus.  You can also look at a test our lead developer set up on jsPerf: JS AppMeasurement jsPerf Test.  Of course you are welcome to set up your own tests but your mileage will vary (especially if you don’t set up the test properly as happened earlier today with an “early adopter”).

js-speed-test

While the new JS file will dramatically improve your efforts to unify web analytics deployments and increase the sophistication of your mobile implementations, there are two limitations you should be aware of:

  1. The new JS file doesn’t currently support TagManager. We’ll be adding support for TagManager later this summer.
  2. The new JS file doesn’t support all Consulting Plugins.  A partial list of supported and non-supported plugins may be found here:  AppMeasurement Plug-in Support. If you’ll be migrating an existing implementation to the new JS file, you will need to remove or update any plugins that aren’t supported. Consulting is currently working to test and upgrade (where necessary) commonly used plugins, and the plugin support documentation above will be regularly updated with these changes.

Ok, now we’ve got that out of the way, let’s walk through a simple deployment and review two of the new utilities in more detail.

Step 1: Download the new JS file from the code manager

You’ve probably noticed we revamped the code manager page.  The new page has links to all the current analytics measurement libraries (including mobile apps) along with links to measurement documentation and version history.

code-manager

Step 2: Configure Above-the-Line Code

Once you’ve downloaded the core JS file from the code manager, you’ll need to add the configuration settings to the top of the file.  When complete, your code will look something like the image below.  You’ll notice the way the instance is instantiated (top two lines of code) is slightly different from the old method—be sure to use this new approach if you’re migrating to the new library.

configure-code

Step 3: Configure Plugins

If you’re doing a first-time deployment, this is where you’ll add plugin and utility functions to enhance the data collected by the core JS file.  If you’re migrating to the new version of JS, here’s where you’ll need to do a thorough review on the plugins you are migrating to ensure every plugin is working as expected.  You may wish to work with Adobe Consulting Services if you have a complex plugin setup.

Step 4: Configure Utilities

We’ve added several utilities to cover a few common plugin use cases.  If you’re using getqueryparam, linkhandler, url encoding, or setting cookies in your core JS file, you should replace the old functions with the new core utilities.  Please note the getQueryParam plugin is not compatible with the new version of JS.  You will need to ensure you replace the plugin with the utility—I’ll show you how to do that next.

Util.getQueryParam

Let’s assume for a minute you have a campaign that points people to your website.  The link appends the query string “cid=springpromo” in the url and you are currently passing “springpromo” into the campaign variable via the getQueryParam plugin.  The following code demonstrates how you would migrate this functionality.

Old Code

/* Plugin Config */
s.usePlugins=true
function s_doPlugins(s) {
/* Add calls to plugins here */
s.campaign=s.getQueryParam(‘cid’);
}
s.doPlugins=s_doPlugins
/************************** PLUGINS SECTION *************************/
/* You may insert any plugins you wish to use here.                 */
/*
* Plugin: getQueryParam 2.4
*/
s.getQueryParam=new Function(“p”,”d”,”u”,”h”,””
+”var s=this,v=”,i,j,t;d=d?d:”;u=u?u:(s.pageURL?s.pageURL:s.wd.loca”
+”tion);if(u==’f’)u=s.gtfs().location;while(p){i=p.indexOf(‘,’);i=i<0″
+”?p.length:i;t=s.p_gpv(p.substring(0,i),u+”,h);if(t){t=t.indexOf(‘#”
+”‘)>-1?t.substring(0,t.indexOf(‘#’)):t;}if(t)v+=v?d+t:t;p=p.substrin”
+”g(i==p.length?i:i+1)}return v”);
s.p_gpv=new Function(“k”,”u”,”h”,””
+”var s=this,v=”,q;j=h==1?’#':’?';i=u.indexOf(j);if(k&&i>-1){q=u.sub”
+”string(i+1);v=s.pt(q,’&’,’p_gvf’,k)}return v”);
s.p_gvf=new Function(“t”,”k”,””
+”if(t){var s=this,i=t.indexOf(‘=’),p=i<0?t:t.substring(0,i),v=i<0?’T”
+”rue':t.substring(i+1);if(p.toLowerCase()==k.toLowerCase())return s.”
+”epa(v)}return””);

New Code

/* Plugin Config */
s.usePlugins=true
function s_doPlugins(s) {
/* Add calls to plugins here */
s.campaign=s.Util.getQueryParam(“cid”);
}
s.doPlugins=s_doPlugins
/************************** PLUGINS SECTION *************************/
/* You may insert any plugins you wish to use here.                 */

Linkhandler

To provide additional flexibility with how you manage link tracking (set additional variables, override link tracking, etc.), the following variables are populated before the doPlugins function runs: linkType, linkName, linkURL, linkObject.  Here’s a quick example of how you would use the new linkhandler capability to set a context variable with the link name.  I know this is a simple example and I’m sure you’ll think of several more complex and useful things you could do.

/* Plugin Config */
s.usePlugins=true
function s_doPlugins(s) {
/* Add calls to plugins here */
    if(s.linkObject && s.linkType==’e’){
    s.contextData['exit']=s.linkName;
   }
  }
s.doPlugins=s_doPlugins
/************************** PLUGINS SECTION *************************/
/* You may insert any plugins you wish to use here.                 */

More on linkObject

That was an admittedly simple example; and, if you’re still reading, you deserve a bit more detail around how to best utilize the linkObject as there are a few gotchas. If a link is coded with an onclick that sends data using s.t() or s.tl(), doPlugins will run twice: once with the original onclick, wherein linkObject, linkType and linkName or linkURL will be set, and these variables can be used to set linkTrackVars and other variables, or abort tracking.

Then, doPlugins will run a second time, this time because of the event listener attached to the body or link by the core JS file. This time, the linkObject, linkType, linkName and linkURL will be empty. If you were to set linkType and linkName this time (for any reason), you would send another server call right after the first one. This would be bad. As such, it is strongly recommended that before considering using linkHandler-like functionality, the customer check for a value of linkObject like this:

    if(linkObject){
       // evaluate linkType, linkName, etc.
       // walk up the DOM using linkObject, looking for stuff
       // set variables appropriately
    }

When something is clicked, the JS file evaluates the clicked object to see if linkObject should point to it. If it should not, it will walk up the DOM looking for a parent that matches specific criteria. linkObject will only point to an object when that object or a parent of that object:

  • Has an onclick (not an event listener)
  • Is an anchor tag with an href or an area tag with an href
  • Is a form submit button with a value or an input with a value
  • Is an image with a src attribute

A common use case is for users to look at a DOM element to see whether it’s a child of a DIV or other element that meets some criteria, such as whether it has an ID or class that equals “top_stories” or something similar. If walking up the DOM, users will create a loop looking at the parentElement or parentNode until they are both not set or the body tag is reached. This would look something like this:

    // WARNING! UNTESTED CODE !!!
    var o = linkObject;
    while(o){
       o = o.parentElement ? o.parentElement : o.parentNode;
       if(o){
          if(o.id = “top_stories”){
             s.prop10=”Top Story”;
             s.linkType=”o”;
             s.linkName=”Top Stories”;
             break;
          }
       }
    }

 Step 5: Verify New Code

Once you’ve completed the changes and pushed the file to your web environment, you should verify the file is sending analytics requests and the code version now starts with JS- in the debugger or packet sniffer of your choice.

verify-code

Now you’ve lightened up, you’re welcome to go back to whatever you were doing.  As for the guys in the picture, I’ll let you decide if they are jazzed about the new capability or are acting like the 3 wise monkeys.

A final note on migration

If you’re ready to migrate to the new version of the JS but are currently blocked by a plugin that isn’t currently supported in the new version, please bring this to the attention of your consultant or account manager to help Consulting prioritize plugin updates.

Documentation

You can find full documentation on JS AppMeasurement within the implementation guide in the knowledge base.

Observations or questions?  Add a comment below.

0 comments