DevX HomePage

Analyzing Your RIA: Silverlight Makes it Easy

Historically, tracking how users interact with a RIA was almost never done. Adding the necessary analytic code to your RIA was usually an afterthought at best. But with Microsoft® Silverlight™, designers and developers have an easier time of building tracking information in any time during development.

Earlier this year, Michael Scherotter and William Garrison produced an excellent article on "Using Web Analytics with Microsoft Silverlight". The Scherotter/Garrison article was targeted at Silverlight 1.0 and given the recent release of Silverlight 2 RC0, and the even more recent final release of Silverlight 2, the time appears ripe for an update to this topic to address the issue of how to effectively use web analytics with Microsoft Silverlight 2.

Web analytics is essentially a tool for measuring and evaluating web site traffic in order to determine some mix of the following:

The language of Web analytics includes:

Web analytics services take the raw data collected from a given website and display it in a collection of reports which are designed to permit a site administrator to evaluate the performance of the website pursuant to the criteria described above.

Figure 1. This screenshot from Google Analytics shows 352 visits by 253 unique visitors with 990 pageviews during the applicable tracking period. Hits are not displayed.

There are a number of commercial and free Web analytics options including WebTrends, Omniture, Microsoft AdCenter Analytics (currently in Beta with only limited public availability) and Google Analytics, but in the interest of space, I will confine my examples to Google Analytics. The principles of these examples should generally be applicable to other Web analytics solutions as well.

Click-Stream Tracking for Silverlight 2 Applications
Obviously understanding your customers and how they react to your website is just as important for a website with Silverlight content as one without. For example, it could be very useful to a site administrator to know what percentage of users choose the "Skip Introduction" link or how often users click on the "Instructions" button.

Figure 2. This screenshot shows a typical single page Silverlight application with an animated introduction and a button for displaying usage instructions.

However, the measurement process for Web analytics is linked to navigation through multiple web pages and Silverlight content frequently compresses user interaction into a single page. Thus, in order to generate an accurate view of user activity with respect to Silverlight content, a modified analytics implementation is required.

Google has two versions for the tracking code required to monitor websites which it refers to as the old (or legacy) method (urchin.js) and the new method (ga.js). This article will illustrate how to interface between Silverlight content and Google Analytics using either method, the older one first.




The Legacy Web Tracking Method
On a standard web page, the older implementation for Google Analytics is to include the following text within the <head> section of the page:

<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"></script>

The effect of this reference is to call the method urchinTracker() contained in the file urchin.js each time that the page is loaded. This method then collects the appropriate data and transmits it back to the Google Analytics server where it can later be incorporated into various reports which the site administrator can access.

This structure, while designed for standard websites, nevertheless still works nicely where each element in a Silverlight website is contained on a separate page, as illustrated in the following screenshot taken from the TravelsWithCal website:

Figure 3. The TravelsWithCal Deep Zoom Zone

In this case each link leads to a separate page containing an independent Silverlight Deep Zoom image. The appropriate analytics technique in a case like this, therefore, is to simply include the standard tracking script in the <head> section of each page—just as would be done in a non-Silverlight context.

Now consider the following website design which was created specifically to illustrate the principles enumerated in this article. In this Travel IQ Quiz, a user is offered a choice of four categories (Rivers, Churches, Roads and Museums). Assume that the website administrator would like to know what percentage of users chose any particular category. In this case, the selection of any one of the radio buttons will not switch to a new page but instead only load the image control with a new photo from the selected set.

imgPhoto.Source = new BitmapImage(new Uri("Images/MassiveOverload.jpg", UriKind.Relative));

Figure 4. Travel IQ Quiz illustrates a typical Silverlight application which consists of only a single page.

Not withstanding that the structure of this website does not involve multiple pages, there is a solution which is referred to by Scherotter and Garrison as a "pseudo page view" technique. The urchinTracker() method takes a single parameter of data type string representing the name of the current page. The trick is to call this method passing in the name of a pseudo page representing the particular user action which you would like to track.

This is roughly the equivalent of tracking JavaScript events, instructions for which are covered in the Google Analytics help files. These instructions require that the pseudo page parameter must begin with a forward slash and must be in quotes. These pseudo pages can be organized into any desired directory style structure.

So to track the selection of user choices of the different categories in my Travel IQ Quiz, we need to put an entry in each radio button's Checked event handler which will call the urchinTracker() method and pass in a string value representing the corresponding category. (Calling JavaScript code from managed code typically uses the HtmlPage.Window.Invoke() method. HtmlPage is a Silverlight .NET Framework class designed to permit access to a browser's DOM. The HtmlPage's Window property returns a reference to the browser's JavaScript window object. From there, the Invoke() method can be used to execute any available JavaScript method.)

HtmlPage.Window.Invoke("urchinTracker", "/RiversPhotoCollection");

HtmlPage.Window.Invoke("urchinTracker", "/ChurchesPhotoCollection");

HtmlPage.Window.Invoke("urchinTracker", "/RoadsPhotoCollection");

HtmlPage.Window.Invoke("urchinTracker", "/MuseumsPhotoCollection");

Since the urchinTracker() method believes, for example, that RiversPhotoCollection is a web page, it will record one pageview each time that the Checked event is raised for the Rivers radio button.

Please note that the directive "using System.Windows.Browser;" is required in order to reference HtmlPage from within the C# code.

The New Web Tracking Method
The new Google Analytics web tracking method requires the following text to be included in the <head> section of each trackable web page:

      <script type="text/javascript">

          var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");

          document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));

    </script>

    <script type="text/javascript">

        var pageTracker = _gat._getTracker("UA-xxxxxxx-x");

        pageTracker._trackPageview();

    </script>

An apparent goal of this new structure is to accommodate both secured (https) and unsecured (http) web pages. In addition, the Google Analytics online instructions point out that using the new tracking method will permit a site administrator to access new features for this service as they are added. Obviously, therefore, the new method is recommended.

In this case, the _trackPageview() method contained in the ga.js file is called to collect and upload the desired tracking data. However, this new web tracking method uses a slightly different technique to call this function. It requires a reference to a pageTracker object in order to perform this task. This difference, in turn, requires a slight modification of the technique described above to call the data collection function (_trackPageview()).

In addition to putting the above standard tracking code on the Travel IQ Quiz web page, it is necessary to add another JavaScript entry (also in the <head> section of the web page):

    <script type="text/javascript">

        function CallPageTracker(strPseudoPage) {

            var pageTracker = _gat._getTracker("UA-xxxxxxx-x");

            pageTracker._trackPageview(strPseudoPage);

        }

    </script>

The code to call this JavaScript function is very similar to the code required by the legacy method:

HtmlPage.Window.Invoke("CallPageTracker", "/RiversPhotoCollection");

HtmlPage.Window.Invoke("CallPageTracker", "/ChurchesPhotoCollection");

HtmlPage.Window.Invoke("CallPageTracker", "/RoadsPhotoCollection");

HtmlPage.Window.Invoke("CallPageTracker", "/MuseumsPhotoCollection");

The difference between the two techniques is that instead of calling the collection method directly, we call a function of our own creation which in turn calls the Google Analytics collection method.

The following screenshot shows how Google Analytics then records this tracking information:

Figure 5. Screenshot of Content Overview showing pageviews for our collection of real and pseudo pages.

Notice how each of the pseudo page views is treated in the identical fashion as an actual webpage. This is true even with respect to the detailed reports which are derived from this Content Overview, as illustrated in the following screenshot.

Figure 6. Screenshot of Content Performance report showing additional detail.

Thus we see that although tracking Silverlight content requires a modification of the standard web tracking techniques, the changes necessary are relatively easy to implement. And once these tracking mechanisms are in place, it is possible to track user interaction with Silverlight content just like a standard web page.




Silverlight Analytics Tracking Flexibility
Silverlight analytics tracking typically requires a JavaScript entry on the web page containing the Silverlight content and an entry in the event handler corresponding to the user action which you wish to track that calls a JavaScript method to collect the necessary tracking information and forward it to the analytics server. It should be evident that this tracking code can be added at any time, including to existing Silverlight applications, with only modest effort. This is an important consideration since it means that it is never too late to start tracking your users to improve the role of your website in attaining your company's business objectives.

While not illustrated by the examples in this article, it would also be possible to collect tracking data for use by multiple analytics services. Of course, in a case like that the effect on application performance should be carefully evaluated.

Silverlight Analytics—CodePlex
Recently, the Silverlight Analytics Library appeared on CodePlex. This library offers some advantages over the techniques described above, so let's take a look at this option in my article.

Although Google Analytics Event Tracking was introduced in October 2007, it is still in beta. The help files for Google Analytics include an explanation of Event Tracking without mentioning that it has not yet been released. The following discussion therefore assumes that eventually it will be released and that for those who are less patient, it may be possible to enroll in the beta program. Until actual release, however, unless you are participating in the beta program, even though you have the appropriate event tracking code in your web pages and Silverlight application, the reports from Google Analytics will not include any event tracking information.

GA Event Tracking can provide data both on events and sub-categories of events. Picture this as being similar to grouping subtotals in a spreadsheet. For example, assume that your website contains a number of videos hosted on Silverlight Streaming. In addition to knowing which videos your users are playing, you may well want to know how often these videos were paused and restarted or stopped prior to completion.

The Silverlight Analytics Library represents a C# wrapper on the GA Event Tracking interface which permits a developer to choose one of three overloaded TrackEvent methods to pass in the required Category and Action parameters with or without either or both of the optional parameters, Label and Value. Each of these methods assumes that an EventTracker object has been created with a constructor which specifies the applicable Category.

         public void TrackEvent(TAction action)

        {

            if (Tracker != null)

            {

                Tracker.Invoke("_trackEvent", Category.ToString(), action.ToString());

            }

        }

         public void TrackEvent(TAction action, String label)

        {

            if (Tracker != null)

            {

                Tracker.Invoke("_trackEvent", Category.ToString(), action.ToString(), label);

            }

        }

         public void TrackEvent(TAction action, String label, int value)

        {

            if (Tracker != null)

            {

                Tracker.Invoke("_trackEvent", Category.ToString(), action.ToString(), label, value);

            }

        }

To use the Silverlight Analytics Library, all you need to do is to include the same JavaScript reference to Google Analytics web tracking which is described at the beginning of the New Web Tracking Method section, above. Then add a reference to the SilverlightAnalytics.dll to your Silverlight application. Next you will want to create enums to hold your lists of Categories and Actions. Then in your event handlers for the events you want to track, create an instance of the SilverlightAnalytics EventTracker class and call one of the three methods specified above with the necessary parameters.

From the GA Event Tracking reports it would then be possible to determine the aggregate number of how many users viewed any video, the number of users who viewed each individual video, and for each video, how many users pressed Play, Pause or Stop—and how many times. Moreover, if each of these Labels (Play, Pause, Stop) were assigned a numerical value (via the Value parameter), aggregate values could be determined for and across each Label. Accordingly, when and if GA Event Tracking becomes publicly available, a significant additional level of potentially useful tracking detail should become available.

The Silverlight Analytics Library also contains a method which permits tracking on both a real and pseudo pageview basis comparable to the method described in the New Web Tracking Method section above. Overloads permit the passage of either a Uri or a string.

        public void TrackPageview(Uri pageUrl)

        {

            TrackPageview(pageUrl.ToString());

        }

 

        public void TrackPageview(String pageUrl)

        {

            Tracker.Invoke("_trackPageview", pageUrl);

        }

Justin Cutroni has prepared a good three part series explaining how to use Google Analytics Event Tracking. Please note that there have been some changes to the GA Event Tracking structure since the Cutroni articles were written, particularly that the "_trackEvent" method can now be called directly from the pageTracker object rather than having to instantiate a separate eventTracker object for each category that you want to track.

Finally, it should be noted that while the Silverlight Analytics Library offers the convenience of calling GA Event Tracking directly from inside a C# event handler, it would also be possible to call GA Event Tracking indirectly by calling a JavaScript function from the C# event handler using a technique similar to that described in the New Web Tracking Method section above. Generally, however, you will find the Silverlight Analytics Library approach to be much more convenient, particularly if you are uncomfortable with JavaScript.

Summary
The standard mechanism for retrieving tracking data from web pages relies on client-side JavaScript. Although a major achievement of Silverlight 2 is support for client-side Microsoft .NET® code (Visual C#® or Visual Basic.NET®), it nevertheless remains fully compatible with JavaScript. As we have seen, tracking user activity within Silverlight content usually will require that the .NET code call a corresponding JavaScript method in order to record the appropriate tracking information.

Also since standard tracking mechanisms for web analytics are very much page oriented, in the case of Silverlight content it is necessary to use a pseudo page approach. As it turns out, this approach is relatively easy to implement and gives you great flexibility in how you create the structure that you can use to organize your tracking information. Any event—from a button click to a list box selection, even a mouseover—can be assigned a pseudo page identity and tracked in the same fashion as the navigation to a different web page.

With this tracking information, a site administrator or a website developer is in a position to continually improve the design of the website to enhance visitor experiences and, more importantly, to increase the website's contribution to the organization in achieving its overall business goals.

Links

  • Using Web Analytics with Microsoft Silverlight (Scherotter & Garrison)


  • General Explanation of Web Analytics (Wikipedia)


  • List of Web Analytics Software (Wikipedia)


  • Using Google Analytics with Silverlight 1.1 (Jeff Wilcox blog article—using the legacy Google Analytics tracking structure)


  • Walkthrough: Calling JavaScript from Managed Code (MSDN Help File)


  • Communicating Between JavaScript and Silverlight (Mike Snow blog article)


  • Which version of the tracking code am I using? (Google Analytics Help File)


  • Inserting tracking code for JavaScript events (Google Analytics Help File)


  • Silverlight Analytics Library (CodePlex project by Cory King)


  • Google Analytics Event Tracking (Google Analytics Help File)


  • * This article was commissioned by and prepared for Microsoft Corporation. This document is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.


    Cal Schrotenboer is a C# developer with experience in building Windows Forms application front ends for SQL Server databases. He also teaches programming classes at Foothill College in Los Altos Hills, California and Microsoft Network Administration (MCSE) classes at Mission College in Santa Clara. Cal maintains a WPF blog at www.WPFLearningExperience.com. His outside interests include travel and photography (www.travelswithcal.com).