Online Applications and highly-interactive web sites written in full-on programming languages are becoming the norm on the web, not the rare exception. Measuring these applications is challenging for a whole
host of reasons. But one of the biggest problems right now is how clumsy the javascript tagging method is when applied to applications.
Most measurement systems now work similarly – they rely on a small javascript program (the tag) that allows a coder to customize the values for certain variables and then call a function that assembles those values, adds a set of environmental variables (like browser and referring site), creates an image request and then executes that image request. All of the custom and environmental variables are passed as parameters in the image request and are decoded by the vendor when the request is logged on their end.
Think about it – all the fuss and muss of tagging – just to make a call to another server and pass a few values. In the world of applications, there are many ways of handling this basic task, by far the most common being to use a web service. Web services are vastly more convenient for the application developer than the current method (which is well suited to static HTML). Indeed, it's hard to imagine a more primitive interface for web communications than passing parameters in image requests.
The virtues of web services include the fact that they are directly supported within every significant programming language (including direct support within the programmers development environment), they provide methods that allow for back-and-forth communication and error-handling when necessary, they provide more control over the nature and amount of information passed, and they typically encapsulate the information passing into much more logical and understandable programmatic units.
It’s true that some measurement vendors provide data insertion APIs. Omniture, for example, has one. But the Omniture Data Insertion API is not a real web-service. It’s just a ”post” based mechanism for sending data. It’s might be the right method to select if you’re coding SiteCatalyst measurement in an application right now – but it’s hardly a robust interface.
But to me, the most important part of building a good interface between application system and measurement system isn’t the handshake mechanism, it’s the structure of the programmatic interface.
Here’s some sample SiteCatalyst code that might get attached to a click-handler when an event is firing:
var s=s_gi('rsid');s.linkTrackVars='eVar34,prop8,eVar8,prop9,eVar9,prop32,eVar32,eVar50,events';s.linkTrackEvents='event3';
s.eVar34='+1';
s.prop8='[Section]:upload files'; s.eVar8='[Section]:upload files';s.prop9=s.pageName+':[Section]:upload files';s.eVar9=s.pageName+':[Section]:upload files';s.prop32=s.eVar32='upload files';s.eVar50='+1';s.events='event3';s.tl(this,'o','upload files');These 13 lines of code create the basic SiteCatalyst measurement object (s), tell SiteCatalyst which variables to pass (linkTrackVars), which events to pass (linkTrackEvents), assign seven different variables and one event, and then call the s.tl function that generates and fires the image request.
Strewing chunks of code like this – even if it’s translated into C# or java - all over your application makes for an incredibly messy situation: it’s hard to document, hard to code, hard to test, and very hard to maintain. And like most poor coding mechanisms, it means that if you want to change measurement systems, you’re faced with a significant re-wiring task.
If this is the wrong way to integrate measurement into an application, what’s the right way?
Well, it isn’t to give the programmer a function call like this:
doPageView(“pagename”, “events=1,3,5”, “evar1=test;evar2=test2”, “prop1=red”);
In truth, even this would be better than what we have now (though it’s easy enough to create this sort of wrapper). But this simple function library approach doesn’t create a structure that embeds measurement logically inside the application.
What I’d like to see is a system where you started with a basic measurement object. This object could be instantiated once by the application (though applications could use more than one) and would contain, at minimum, the target account information and the configuration of environmental variables (what needs to be pulled and passed).
Ideally, environmental variables would only be passed once on invocation of the application (since apps aren’t stateless like the web, the challenge of inferring sessions and the necessity for re-passing environmental information with every request doesn’t exist). This would dramatically reduce the amount of information required with each call and the corresponding network bandwidth required.
Underneath this global measurement object would exist one or more measurement objects that inherit the global state and allow for custom mappings of application variables. The custom mappings would let the developer populate measurement variables from object properties (like Name, ID, Value or isVisible), application variables, static values or special function.
In this way, a measurement variable could be populated with the Name Property (for example) of any object to which to which it was attached. If attached to a Form Object, it could automatically create something like a pagename variable for an application by mapping the Form's "name" property to the measurement pagename variable.
The measurement object could also be configured to support any or all of the default or specific methods that objects in the development environment have. In other words, a measurement object could be configured with a specification for “load”, “unload”, “click”, etc. This would allow the developer to automatically fire a measurement call in response to either specific functions (like a search) or general functions (like a form load).
With this approach, the developer can take advantage of built-in UI constructs and also manage a small set of application specific variables that will automatically be translated into the measurement system equivalents whenever an actual measurement call is made.
When I create an object in the interface, I would then attach my measurement object to it. When the object is loaded, any handlers for the measurement object would be fired if present. It would automatically set its values, give the programmer an opportunity for a call-back (which should be rare) and then fire the request.
This is rather abstract, so let me show how this work in a more concrete fashion.
I’d start with a measurement object in which I would set the global information about the account (and maybe the vendor) I’m sending information to along with the environmental variables I want to pass on invocation.
Next, I’d create a custom variable object that described the specific variables I want to pass. Let’s suppose that I’m working on a Mapping Application and I want to collect the viewed area (the region/country/city shown in the Map Title), the map view (road, topo, satellite, etc.), the map state (overlays, zoom level), the language of the map, and the visitor identity. I would map each of these application variables to a specific measurement object variable. Next, I’d assign the click-handlers I want the measurement to fire on (I may want it on every re-draw but I might also want it on a more limited set of actions such as onSearch and onMapChange). Finally, I’d attach the measurement object to the underlying UI object.
That’s pretty much it. Once the object is attached, the programmer is done. When the object to which the measurement is attached fires an appropriate handler, the object would inherit its default state, populate the variables (like viewed area, map state, etc.), and then fire the measurement request.
Depending on my application, I might need only one custom measurement object or I might need quite a few. But with this type of system, the measurement objects would be embedded into the underlying GUI objects and their handlers. The measurement layer would deeply in-grained, it would provide inheritance, and it would provide configurability. It would be much, much easier to maintain such a system. The measurement objects themselves would be compact and discrete and they would be directly attached to the objects in which they reside.
Having a measurement integration at this level inside an application development framework would make the development process dramatically easier. Indeed, it would be possible to achieve a very high-level of measurement with a simple default configuration of the measurement object that might simply “fall-out” of a single drag-and-drop of the measurement object into the application. Such a default configuration might capture the object name and title of every form on load and unload, the object name and title of every “play” movie action, and the selected value from any Combo-Box. But it would also provide a high-level of control within the application for measurement at a very fine-grained object level.
As I mentioned in my first post, there really aren’t any serious barriers to building this type of system. There are probably different ways of achieving a deep measurement integration or designing the measurement objects – and I’m not confident that what I’ve suggested is the exactly right answer. But some form of deeply embedded measurement at the object level within the app framework seems both inevitable and right. Having an embedded measurement system won’t solve all the problems in application measurement, but it would be a big step in the right direction.
In my next post, I’ll take up a thornier issue – the right measurement paradigm in a world where page views and link clicks aren’t the ultimate measurement objects!
Recent Comments