views:

121

answers:

1

I have a widget that is inserted on numerous Web pages. It's composed of some JavaScript that loads an HTML document from my server (as JSONP) which is then inserted into a dynamically created <iframe> on the page where the widget is deployed.

I use Clicky for analytics/tracking to measure the number of pageviews that my widget's host page receives. Recently, I needed to go a bit further, to track the number of actual views of the widget itself. The purpose of this data is to more accurately interpret the performance of the widget at generating clickthroughs - that is, if a visitor doesn't scroll down the host page far enough to see my widget in the first place, there's no way that I could have inspired a clickthrough.

To achieve this tracking, I wrote a function that subscribes to the browser's "onscroll" event; basically, each time it's called, it compares the distance between the top of the host page document and the top of the widget, to the distance that the viewport is scrolled down from the top of the host page plus the height of the viewport and half the height of the widget. When the latter exceeds the former, the widget can be assumed to be halfway visible in the browser viewport.

When the function determines that this has happened (the widget needs to remain in the viewport for 2 seconds or more to count), it logs an "action" to Clicky, i.e., informs the analytics software that this has happened. This is done by calling a predefined function that loads an "image" from Clicky's server - basically a way to use a cross-domain GET request to communicate some tracking data.

The problem is that this request takes time - on average, a little over a second - to complete, and during that time, the browser window can't be scrolled. This is a showstopper for me. A slight delay - ideally well under a half second - is acceptable, but nothing approaching a second will work.

I've done my best to analyze the data that various performance tools generate (Firebug's Net Panel, Google Page Speed), but I'm at a loss to explain what is happening.

I would be extremely grateful to anyone who can provide some insight into what is happening, or even better yet, share a possible solution(s) to reduce or eliminate the blocked browser scrolling. The time to fulfill the request is unimportant to me, but the amount of time that the scrollbar is "stuck" is critical. For example, is there a way to make this request to Clicky without interrupting the browser's scrollbar functionality?

As a proof-of-concept of my code, I had created a prototype, viewable here:

http://troy.onespot.com/static/3128/prototype.html

When you scroll the page down until the middle of the gray box enters the viewport for 2 seconds or more, an indicator that a "widget view" has been logged will appear on the top-right of the screen.

(I've only tested this code to work in Firefox 3.0 or more recent versions - in fact, aside from possibly Safari, it's unlikely to work elsewhere, as it doesn't honor cross-browser differences in dimension properties.)

Also, here is a screenshot of Google's Page Speed tool's output during this logging:

http://img.skitch.com/20100121-t6bt1wauaar2drg1xdmwk9g4sb.png

To generate this, I scrolled/jiggled the page constantly as I eased the gray box into the viewport. The function fired by the "onscroll" event can be seen working repeatedly as a broken black line across the top of the output. As you can see, as soon as the Clicky logging happens (the large gap in the broken black line), approximately 1.2 seconds elapse where scrolling is not possible. I have no idea what is happening during the empty span in the latter half of that period, nor do I really understand why the entire period prevents scrolling.

Firebug's Net Panel shows a shorter period of elapsed time (though it still feels like a second or more, subjectively):

http://img.skitch.com/20100121-pwf1ifngffsnqm8qekmm8wp9mt.png

In this case, the vast majority of time (544ms) is spent in the "Blocking" stage, which makes no sense to me; my understanding was that this stage is only encountered when the request is in a queue because the maximum number of requests per hostname are already being made.

Any ideas, suggestions, or other insight would be very much appreciated. Thanks!

+1  A: 

Set the timer to 1 and not 0 in the clicky_custom config object. There is a bug in their code that says that if the timer is 0 then wait 500ms.

I found this out using firebugs profile and their init fuction was taking a the time. The code was somthing like timer = config.timer|500. config.timer will evaluate to false so 500 was returned.

David Raznick
David, if I could vote you up 100 times, I would. ;-) That fixed it beautifully. Thank you SO much.
Bungle