Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Batched, on-demand tracker hash fetching.
Browse files Browse the repository at this point in the history
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
chromakode committed Mar 9, 2013
1 parent a31296f commit c32fdd1
Showing 1 changed file with 47 additions and 58 deletions.
105 changes: 47 additions & 58 deletions r2/r2/public/static/js/analytics.js
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,
Expand All @@ -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({
Expand All @@ -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) {
Expand Down

0 comments on commit c32fdd1

Please sign in to comment.