Permalink
Browse files

Batched, on-demand tracker hash fetching.

Instead of fetching tracking hashes for all applicable elements on the
page, fetch only the visible ones. Uses _.debounce() to batch up
requests during the init process.
  • Loading branch information...
1 parent a31296f commit c32fdd1adf9b965009f1a0a968c9cbdca53404ca @chromakode chromakode committed Feb 26, 2013
Showing with 47 additions and 58 deletions.
  1. +47 −58 r2/r2/public/static/js/analytics.js
@@ -1,22 +1,23 @@
r.analytics = {
trackers: {},
+ _pendingTrackers: {},
init: function() {
// these guys are relying on the custom 'onshow' from jquery.reddit.js
$(document).delegate(
- '.promotedlink.promoted, .sponsorshipbox',
+ '.promotedlink.promoted, .sponsorshipbox[data-fullname]',
'onshow',
- $.proxy(this, 'fetchTrackersOrFirePixel')
+ _.bind(function(ev) {
+ this.fetchTrackersOrFirePixel(ev.target)
+ }, this)
)
$('.promotedlink.promoted:visible, .sponsorshipbox:visible').trigger('onshow')
$('form.google-checkout').on('submit', this.fireGoogleCheckout)
$('form.gold-checkout').one('submit', this.fireGoldCheckout)
},
- fetchTrackingHashes: function() {
- var fullnames = {}
-
+ fetchTrackingHash: function(el) {
/*------------------------------------------*
Generates a trackingName like:
t3_ab-t8_99-pics if targeted with campaign
@@ -25,69 +26,57 @@ r.analytics = {
t3_ab- not targeted, no campaign
*------------------------------------------*/
- $('.promotedlink.promoted, .sponsorshipbox')
- .each(function() {
- var thing = $(this),
- fullname = thing.data('fullname'),
- sponsorship = thing.data('sponsorship'),
- campaign = thing.data('cid')
-
- if (!fullname || fullname in r.analytics.trackers)
- return
-
- var trackingName = fullname
-
- if (sponsorship)
- trackingName += '_' + sponsorship
+ var $el = $(el),
+ fullname = $el.data('fullname'),
+ sponsorship = $el.data('sponsorship'),
+ campaign = $el.data('cid'),
+ trackingName = fullname
- // append a hyphen even if there's no campaign
- trackingName += '-' + (campaign || '')
+ if (sponsorship)
+ trackingName += '_' + sponsorship
- if (!r.config.is_fake)
- trackingName += '-' + r.config.post_site
+ // append a hyphen even if there's no campaign
+ trackingName += '-' + (campaign || '')
- thing.data('trackingName', trackingName)
- fullnames[fullname] = trackingName
- })
+ if (!r.config.is_fake)
+ trackingName += '-' + r.config.post_site
- var xhr = $.ajax({
- url: r.config.fetch_trackers_url,
- type: 'get',
- dataType: 'jsonp',
- data: { 'ids': _.values(fullnames) },
- success: function(data) {
- $.extend(r.analytics.trackers, data)
- }
- })
+ // if we don't have a hash or a deferred fetch, queue a fetch
+ if (!(trackingName in this.trackers)) {
+ this._pendingTrackers[trackingName] = this.trackers[trackingName] = new $.Deferred
+ this.fetchTrackingHashes()
+ }
- _.each(fullnames, function(trackingName, fullname) {
- this.trackers[fullname] = xhr
- }, this)
+ return this.trackers[trackingName]
},
- fetchTrackersOrFirePixel: function(e) {
- var target = $(e.target),
- fullname = target.data('fullname')
-
- if (!fullname)
- return
-
- if (!(fullname in this.trackers)) {
- this.fetchTrackingHashes()
- }
+ fetchTrackingHashes: _.debounce(function() {
+ var toFetch = this._pendingTrackers
+ $.ajax({
+ url: r.config.fetch_trackers_url,
+ type: 'get',
+ dataType: 'jsonp',
+ data: {'ids': _.keys(toFetch)},
+ success: function(data) {
+ _.each(data, function(hash, trackingName) {
+ toFetch[trackingName].resolve(trackingName, hash)
+ })
+ }
+ })
+ this._pendingTrackers = {}
+ }, 0),
- $.when(this.trackers[fullname]).done(_.bind(function() {
- this.fireTrackingPixel(target)
+ fetchTrackersOrFirePixel: function(el) {
+ this.fetchTrackingHash(el).done(_.bind(function(trackingName, hash) {
+ this.fireTrackingPixel(el, trackingName, hash)
}, this))
},
- fireTrackingPixel: function(thing) {
- if (thing.data('trackerFired'))
+ fireTrackingPixel: function(el, trackingName, hash) {
+ var $el = $(el)
+ if ($el.data('trackerFired'))
return
- var trackingName = thing.data('trackingName'),
- hash = this.trackers[trackingName]
-
var pixel = new Image()
pixel.src = r.config.adtracker_url + '?' + $.param({
'id': trackingName,
@@ -99,7 +88,7 @@ r.analytics = {
// (e.g. it has an @ in it), then setting the href replaces the
// text as well. We'll store the original text and replace it to
// hack around this. Distilled reproduction in: http://jsfiddle.net/JU2Vj/1/
- var link = thing.find('a.title'),
+ var link = $el.find('a.title'),
old_html = link.html(),
dest = link.attr('href'),
click_url = r.config.clicktracker_url + '?' + $.param({
@@ -115,11 +104,11 @@ r.analytics = {
link.html(old_html)
// also do the thumbnail
- var thumb = thing.find('a.thumbnail')
+ var thumb = $el.find('a.thumbnail')
save_href(thumb)
thumb.attr('href', click_url)
- thing.data('trackerFired', true)
+ $el.data('trackerFired', true)
},
fireUITrackingPixel: function(action, srname) {

0 comments on commit c32fdd1

Please sign in to comment.