Avoiding race conditions in Google Analytics async

2019-06-03 02:22发布

I am having issues with many of my events (maybe 20%) not getting recorded in Google Analytics. These are all events called with onclick on an image button that posts a form. I believe that the code isn't running fast enough to submit the events to Google before the browser moves on to the next page.

What I would like to do is check the state of _gaq's queue and make sure there are no pending events before completing my Javascript.

_gaq seems a little cryptic to me, but it does have an exposed property - u. I've been testing in Chrome with a simple command of:

console.log(_gaq.u);

Unfortunately, this always returns 0, even if run immediately after the _gaq.push command. Of course, Chrome always seems to get the events sent to Google before the post fires, so I'm not sure if I even can debug in Chrome, since I can't replicate the problem.

Does anyone know if there is a way to get the count of pending items in the queue from _gaq? Is _gaq.u the appropriate property? I would like to do something a little more elegant than just throwing a 100 or 200 ms wait on all my events.

1条回答
我想做一个坏孩纸
2楼-- · 2019-06-03 02:38

_gaq has 2 stages.

First, when its an array, before ga.js has loaded, its a queue of either function names with their arguments, or actual functions.

Then, when ga.js loads, it gets converted into a special object, the queue is processed (the functions are called), and all subsequent _gaq.push() calls immediately execute what they're passed.

At the time that it is still a queue, _gaq is just a normal JavaScript array. So, you can access the number of items that are waiting to be processed with _gaq.length. Once the queue is processed, there is no way the queue.

The onclick race condition issue is a common one. Many people like to get around it by preventing the default action, doing their event track, and then setting a short-timespanned setTimeout that completes the original action.

My preference is to not compromise the user experience just for analytics (and I do this for a living.) So, my solution is to use onmousedown and onkeydown as substitutes (together I refer to them as preclick. It eliminates the race condition, with only minimal false positives, which is good enough for web analytics, which is about approximate models, not scientific accuracy.

Here's an example in jQuery:

$.fn.preclick = function(param) {
    if (!param) {
        return this.trigger("mousedown");
    }
    return this.one("keydown.preclick mousedown.preclick", function(e) {
        if (e.type === "mousedown" || e.which === 13) {
            param.apply(this);
        }
    });
};
查看更多
登录 后发表回答