Optimizing the Tealium tracking snippet
At Takeaway.com we use Tealium for marketing purposes.
As many other tag managers, Tealium offers a handy Javascript snippet to add their features to a website.
In itself there is nothing wrong with the snippet. But as I believe in striving for Excellence, maybe it can be improved upon?
The original snippet, provided by Tealium looks like any other minified JS snippet:
(function(a,b,c,d){
a='//tags.tiqcdn.com/utag/{{ account }}/{{ profile }}/{{ env }}/utag.js';
b=document;c='script';d=b.createElement(c);d.src=a;
d.type='text/java'+c;d.async=true;
a=b.getElementsByTagName(c)[0];a.parentNode.insertBefore(d,a);
})();
At first glance it does not look like it can be improved upon much.
But what does it really look like?
When the code is unpacked and meaningful variable names are applied, the code looks like this:
(function(element, script, tagName, url){
url = '//tags.tiqcdn.com/utag/{{ account }}/{{ profile }}/{{ env }}/utag.js';
tagName = 'script';
script = document.createElement(tagName);
script.src = url;
script.type = 'text/java'+tagName;
script.async = true;
element = document.getElementsByTagName(tagName)[0];
element.parentNode.insertBefore(script, element);
})();
This makes it easy to understand what the snippet does.
Notice anything that could be improved yet?
There are a few things that could be improved upon, both to use less logic and less bytes.
First of all document
isn't passed in as a parameter, lets do that.
Second, the variable for URL isn't needed. It can be in-lined
Next, setting the tag type to text/javascript
isn't necessary.
In HTML5 it is optional and older browsers default to text/javascript
when the type attribute is omitted
Then, the assignment of tagName
can be avoided by passing it in as a value to the function.
This shaves of another couple of characters.
Finally, the async
attribute doesn't need its own assignment value.
We can easily recycle another value as true
.
This gives us:
(function(document, element, script, tagName){
script = document.createElement(tagName);
script.async = script.src = '//tags.tiqcdn.com/utag/{{ account }}/{{ profile }}/{{ env }}/utag.js';
element = document.getElementsByTagName(tagName)[0];
element.parentNode.insertBefore(script, element);
})(document, 'script');
That looks a lot shorter already, but how much will it save when packed?
After packing the code, we get:
(function(u,t,a,g){
a=u.createElement(t);a.async=a.src='//tags.tiqcdn.com/utag/{{ account }}/{{ profile }}/{{ env }}/utag.js';
g=u.getElementsByTagName(t)[0];g.parentNode.insertBefore(a,g);
})(document,'script');
This is 212 characters.
The savings are:
There is yet another alternative: using a <script>
tag.
To quote Google regarding their Alternative async tracking snippet::
While the JavaScript tracking snippet described above ensures the script will be loaded and executed asynchronously on all browsers, it has the disadvantage of not allowing modern browsers to preload the script.
The alternative async tracking snippet below adds support for preloading, which will provide a small performance boost on modern browsers, but can degrade to synchronous loading and execution on IE 9 and older mobile browsers that do not recognize the async script attribute. Only use this tracking snippet if your visitors primarily use modern browsers to access your site.
The script tag would look like this:
<script async src="//tags.tiqcdn.com/utag/{{ account }}/{{ profile }}/{{ env }}/utag.js"></script>
This comes down to 98 characters.
The savings are:
As an added bonus no logic needs to be executed to load the JS file.
Be aware though, as Google warns:
Only use this tracking snippet if your visitors primarily use modern browsers to access your site.
If you have many visitors that still use older browsers, better stick with the snippet.
With a little bit of effort, even code shorter than 250 characters can be improved.
Any thoughts, suggestions or feedback? feel free to comment here or find me on twitter.