TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Deconstructing the Google Analytics tracking script

217 pointsby BillFranklinalmost 8 years ago

22 comments

tkazecalmost 8 years ago
Documented, including the official unminified source, in Google&#x27;s analytics.js reference: <a href="https:&#x2F;&#x2F;developers.google.com&#x2F;analytics&#x2F;devguides&#x2F;collection&#x2F;analyticsjs&#x2F;tracking-snippet-reference" rel="nofollow">https:&#x2F;&#x2F;developers.google.com&#x2F;analytics&#x2F;devguides&#x2F;collection...</a>
评论 #14662223 未加载
acdxalmost 8 years ago
This is just an analysis of the snippet, not the script it loads (www.google-analytics.com&#x2F;analytics.js).
评论 #14662304 未加载
jchwalmost 8 years ago
The reason why the arguments spell isogram is because you can&#x27;t have two arguments with the same letter. So they chose the most meta isogram, &quot;isogram.&quot; Surprised the author missed that and assumed it was just reference to the script itself.
评论 #14662395 未加载
shubhamjainalmost 8 years ago
Something that has always puzzled me is why only GA follows the saner approach to push all the function calls in an array which the async loaded script can pick up later. Many of the popular analytics solutions (like, Segment, Mixpanel) create a factory function that initialises all API calls with a generic body. It seems rather unnecessary and only adds to the boilerplate. Take a look at the GA&#x27;s init code and compare it with Segment&#x27;s [1].<p>[1]: <a href="https:&#x2F;&#x2F;prnt.sc&#x2F;fpj9ec" rel="nofollow">https:&#x2F;&#x2F;prnt.sc&#x2F;fpj9ec</a>
评论 #14662891 未加载
评论 #14665765 未加载
untogalmost 8 years ago
Anyone not wanting to use the JS might be interested to know that the Google Analytics Measurement Protocol is fully documented, and you can create your own front-end implementation, should you wish:<p><a href="https:&#x2F;&#x2F;developers.google.com&#x2F;analytics&#x2F;devguides&#x2F;collection&#x2F;protocol&#x2F;v1&#x2F;" rel="nofollow">https:&#x2F;&#x2F;developers.google.com&#x2F;analytics&#x2F;devguides&#x2F;collection...</a>
评论 #14667762 未加载
评论 #14666047 未加载
评论 #14666132 未加载
Jgrubbalmost 8 years ago
I wrote almost the same post, with almost the same title a couple of years ago - <a href="https:&#x2F;&#x2F;www.ignoredbydinosaurs.com&#x2F;posts&#x2F;239-deconstructing-the-google-analytics-tag" rel="nofollow">https:&#x2F;&#x2F;www.ignoredbydinosaurs.com&#x2F;posts&#x2F;239-deconstructing-...</a><p>I like mine better :)
spullaraalmost 8 years ago
It is pretty obvious that the snippet loads the real script. I expected this article to be about what the actual google analytics tracking script does rather than the tracking script loader.
评论 #14665732 未加载
shrevealmost 8 years ago
I&#x27;m amused by the fact he thinks `array.push(arguments)` inside the nested function evaluates and pushes the arguments from the parent function.
评论 #14664968 未加载
iakhalmost 8 years ago
Tried to search but nothing obvious showed up. What&#x27;s the purpose of the 1 in &#x27;1 * new Date()&#x27;?<p>Edit: found it. Gets the timestamp[1]<p>1. <a href="https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;24182317&#x2F;multiplication-with-date-object-javascript" rel="nofollow">https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;24182317&#x2F;multiplication-...</a>
评论 #14662716 未加载
评论 #14662936 未加载
mrschwabealmost 8 years ago
On a related note, there is an open source Google Analytics alternative in the works:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;vesparny&#x2F;fair-analytics" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;vesparny&#x2F;fair-analytics</a><p>Hope it comes along; there is surprisingly not much else in the way of Node&#x2F;JS based open source web stats&#x2F;analytics solutions.
评论 #14662437 未加载
评论 #14663441 未加载
评论 #14663000 未加载
chrismorganalmost 8 years ago
I have minimised it in my own case to just this (using ga.js instead of analytics.js because this part is shorter—regardless of the fact that ga.js itself is longer—and not worrying about any fanciness that I don’t need):<p><pre><code> &lt;script&gt;_gaq=[[&#x27;_setAccount&#x27;,&#x27;UA-????????-?&#x27;],[&#x27;_trackPageview&#x27;]]&lt;&#x2F;script&gt;&lt;script async src=&#x2F;&#x2F;ssl.google-analytics.com&#x2F;ga.js&gt;&lt;&#x2F;script&gt; </code></pre> With analytics.js:<p><pre><code> &lt;script&gt;ga={q:[[&#x27;create&#x27;,&#x27;UA-????????-?&#x27;,&#x27;auto&#x27;],[&#x27;send&#x27;,&#x27;pageview&#x27;]],l:+new Date}&lt;&#x2F;script&gt;&lt;script async src=&#x2F;&#x2F;www.google-analytics.com&#x2F;analytics.js&gt;&lt;&#x2F;script&gt;</code></pre>
throwaway2016aalmost 8 years ago
The reason it is a function that calls itself is to not pollute the global namespace. The rewritten expanded example leaks &quot;gaScript&quot; to the global namespace which is a little rude if you are injecting your script onto a third-party page and using a random or long function name is not as clean a solution since it still leaves dirt and takes more bytes.
j_salmost 8 years ago
Another interesting aspect of Google Analytics is understanding how fraudsters sneak by, and the discussions here on HN whenever this comes up.<p>Examples:<p>· Hackers Make $5M a Day by Faking 300M Video Views | <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=13219871" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=13219871</a> (6 months ago)<p>· Uncovering an advertising fraud scheme | <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=2333824" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=2333824</a> (6 years ago)<p>Discussions:<p>· Alleged $7.5B fraud in online advertising | <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=9796102" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=9796102</a> (2 years ago)<p>· Inside Google&#x27;s Secret War Against Ad Fraud | <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=9628967" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=9628967</a> (2 years ago)
Exumaalmost 8 years ago
Here&#x27;s something fun for people who wan&#x27;t to customize what it says instead of &#x27;isogram&#x27; (a fun little easter egg)<p><a href="https:&#x2F;&#x2F;isogrammer.com&#x2F;" rel="nofollow">https:&#x2F;&#x2F;isogrammer.com&#x2F;</a>
xg15almost 8 years ago
&gt; <i>Interestingly, the arguments passed to the function spell out i, s, o, g, r, a, m, is a “term for a word or phrase without a repeating letter” (source), which I guess makes sense, given that the script looks like it has the bare minimum of characters possible.</i><p>I thought that was a kind of recursive joke (not necessarily a very witty one) : if they want to make the parameters spell out a word, the word <i>has</i> to be an isogram, otherwise you&#x27;d define a parameter twice. And since &quot;isogram&quot; is an isogram, maybe the temptation was too great..
GrayShadealmost 8 years ago
Looks like the insertBefore call got dropped along the way.
ggambettaalmost 8 years ago
&gt; It seems like a and m are optional arguments. &gt; Now those unused parameters a and m come in handy. No writing var in this script.<p>Precisely. A trick to reduce the character count, nothing more. Love doing this kind of thing (<a href="http:&#x2F;&#x2F;gabrielgambetta.com&#x2F;tiny_raytracer.html" rel="nofollow">http:&#x2F;&#x2F;gabrielgambetta.com&#x2F;tiny_raytracer.html</a>).<p>&gt; Making a.async truthy ensures<p>&quot;Truthy&quot;???
评论 #14662316 未加载
评论 #14662299 未加载
评论 #14662337 未加载
评论 #14662320 未加载
jannekloumanalmost 8 years ago
A tool that generates tracking codes with a customised isogram as parameters: <a href="https:&#x2F;&#x2F;github.com&#x2F;shinnn&#x2F;isogram" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;shinnn&#x2F;isogram</a><p>Example: (function(i, s, o, g, r, a, m) {...}) -&gt; (function(y, c, o, m, b, i) {...})
评论 #14663228 未加载
jagthebeetlealmost 8 years ago
I&#x27;m not sure if it&#x27;s actually intentional, but given the command-queue nature of the ga function, i[r].q&#x27;s resemblance to IRQ could be a cute reference. (Assuming i and r were fixed, p=1&#x2F;26 for using q... science!)<p>(Originally noted in some old article that I can&#x27;t find right now.)
johopalmost 8 years ago
I also liked this deconstruction: <a href="http:&#x2F;&#x2F;code.stephenmorley.org&#x2F;javascript&#x2F;understanding-the-google-analytics-tracking-code&#x2F;" rel="nofollow">http:&#x2F;&#x2F;code.stephenmorley.org&#x2F;javascript&#x2F;understanding-the-g...</a>
kralljaalmost 8 years ago
&gt; An unminified and less convoluted version of the script might look like this:<p>(references to undefined variables `a` and `m` in some sort of IIIFE)
dna_polymerasealmost 8 years ago
Sherlock here discovered that it asynchronously loads the actual script, which he conveniently did not bother to explore further.
评论 #14663057 未加载
评论 #14662285 未加载