Monday, 13 February 2012

Blogger | Statistics with AJAX

Blogger has been receiving numerous updates in the past few months, mainly in the new templates called Dynamic Views. I first rejected the option seeing how little customisability it offered, but it seems like my own template is quickly converging towards what Google's Dynamic Views is like in its core: full of JavaScript and depending on the blog's RSS feed.

I started my journey by writing some JavaScript which would let users navigate through pages without having the page refresh fully via some AJAX calls and DOM replacement.

The instant search, with a scrollable results box
Then I designed the top bar that you can see floating above this post and thought how nice it could be if I could have a semi-instant search (Blogger's search is quite slow). I then thought of a way which involved downloading the RSS feed for the blog, and parsing all text in the feed. I wrote an occurrence based points algorithm which allows for basic search.

Back when I was implementing the instant search, I found that with the RSS feed in my hands, I could load full pages as well! This would allow me to flick through pages on my site almost instantly.

This week, I got around to doing that very job, and if you navigate around a little bit, you will see that page loads are almost instant.

There was one problem though, Blogger statistics were not getting updated...

Pageviews Increase with Dynamic Views?

I remembered claims from various sources that pageviews had increased by twofolds or more with Dynamic Views enabled. Here's what I found from Google's support page:
If you enable Dynamic Views for your blog, you might notice an increase in pageviews. The reason for this is that Dynamic Views provides more specific information about actions on your blog. Specifically, every click to a post is recorded as a pageview. If a reader clicks on 10 posts, you’ll see those clicks recorded as 10 pageviews. In a traditional Blogger template, if a reader enters your blog once, they can scroll through ten blog posts in a single pageview. So while it may appear that traffic to your blog has increased, it's more likely that Blogger is simply recording more accurate data about your blog than was possible in the past.
Hmm interesting...

Naturally, I felt that there must be some JavaScript trickery going on to allow for this to happen. Dynamic Views afterall, is mostly JavaScript!

The 'Hacking'

As expected, the JavaScript source used has been compiled using Google's very own closure compiler, and therefore has been made uglified and obfuscated. A bit of magic with the Online JavaScript Beautifier alleviated that issue somewhat and I started combing through the code to see any evidence of statistics reporting.

Soon enough, I was able to find a piece of code which seemed to be doing the job:
function Rt(a, b) {
    var c = Q.decode(b).normalize().encode();
    b && !a.Lc[c] && !Q.isCrossDomain(c) && (a.Lc[c] = j, Q.decode(b).path != Q.decode(Pt).path && setTimeout(function () {
            type: Ng,
            async: j,
            url: Q.decode(b).param(Ml, 1).param(Uq, 0).encode()
    }, 1E3), window._gaq && b && window._gaq.push([Mj, Q.decode(b).path]))

The window._gaq && b && window._gaq.push([Mj, Q.decode(b).path])) bit is for Google Analytics. The documentation mentions that this is the way to update Analytics for dynamic sites.

The other large piece of code can be translated into the following:
setTimeout(function () {
        type: 'GET',
        async: true,
        url: document.URL+'?dynamicviews=1&v=0'
}, 1000)
This code basically submits an AJAX GET request for the new page, a second after it has been loaded.

I had a good laugh.


If you have not caught on yet, the solution for reporting Blogger statistics on dynamic sites, is simply requesting the page behind your backs! (The delay is to reduce impact on 'loading times')

I have a feeling that while this is the sensible thing to do at the moment - while Dynamic Views is still in development - I find that the quick loading illudes users into thinking either that less bandwidth is being used and/or that their connection is magically fast!

Loading the RSS feeds in the first place, is basically like loading the content of the blog in its entirety and therefore could be almost equivalent to downloading the blog. This would be awesome if you did not have to make all these requests later on while browsing the website!

I would make a careful assumption that the appended parameters, ?dynamicviews=1&v=0 was intended to allow the script to request an empty version of the page. Unfortunately, it does not seem so at the moment.

Ah well, for now I shall use Google's own trick.

Oh, and if you wish to do the same, simply run the last snippet once you've updated the browser history with History.pushState or equivalent.