-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Further optimizing Google Analytics snippet #1660
Conversation
Slightly improved analytics snippet
all in one line
It can get indented nicely
reverted to the original params
for easier comparison...
e=o.createElement(i);r=o.getElementsByTagName(i)[0]; | ||
e.src='//www.google-analytics.com/analytics.js'; | ||
r.parentNode.insertBefore(e,r)}(window,document,'script','ga')); | ||
o.getElementsByTagName(i)[0].parentNode.appendChild(o.createElement(i)).src='//www.google-analytics.com/analytics.js'} |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
even more shorter
e.src='//www.google-analytics.com/analytics.js'; | ||
r.parentNode.insertBefore(e,r)}(window,document,'script','ga')); | ||
ga('create','UA-XXXXX-X','auto');ga('send','pageview'); | ||
(function(b,o,i){b.GoogleAnalyticsObject='g';(b.g||(b.g=function(){(b.g.q=b.g.q||[]).push(arguments)})).l=+new Date; |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
getting back the option to set the variable name
here is versions of this optimized script to choose from: perfect solution - safe for all - same as in the pull request file - 322 characters
if you're not going to change the variable name - 308 characters
if your page MUST got head - 285 characters
if your page must got head and you don't care about costum variable name - 271 characters
|
no parameters at all
not polluting the global namespace
I looked at this new version and compared it to the old. The key thing here is the gzip'd size as this will "always" be served with gzip and it commonly erases many of these hand-tuning improvements.
(I'm gzipping the entire index.html, but probably should be. gzip is cool) Anyways, we end up with a gain of 18 bytes. Due to how TCP works, the boundaries that actually end up affecting download time are at something like 14KB, 44KB, 88KB.
Why? TCP-slow start, basically. Check the next few slides from here: https://docs.google.com/presentation/d/1qoginKKkdrRpIPGjJakt1y17iXsIBSaInaHbR4JyCIk/present?slide=id.gc03305a_0207 tl;dr: Small differences in byte size will not have a significant impact when the total filesize of the payload is within these below buckets.
The boundaries, therefore, where this sort of byte golfing does have impact are around: 14.2K, 42.7K, 99.8K. (These calculations ignore the overhead of HTTP headers. Assuming initial_cwnd of 10 and MSS of 1460.) (off-topic for this issue in particular, but the global disclaimer in this topic is that reducing requests is a better priority. And understanding the critical path is a more holistic way than targeting either bytes or requests.) |
e.src='//www.google-analytics.com/analytics.js'; | ||
r.parentNode.insertBefore(e,r)}(window,document,'script','ga')); | ||
ga('create','UA-XXXXX-X','auto');ga('send','pageview'); | ||
(function(b,o,i,l){GoogleAnalyticsObject=l;(b[l]=b[l]||function(){(b[l].q=b[l].q||[]).push(arguments)}).l=+new Date; |
This comment was marked as abuse.
This comment was marked as abuse.
Sorry, something went wrong.
wrapped lines
Personally loving @mamathiasbynens suggestion |
👍 to @mathiasbynens's idea! |
I really like @mathiasbynens ga snippet. |
Supporting @mathiasbynens because of its simplicity and use of async. (: |
So sorry because I'm not skilled with JS. <script async src='//www.google-analytics.com/analytics.js'></script>
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-XXXX-Y', 'auto');
ga('send', 'pageview');
</script> Why can't we simply add |
Hi @mathiasbynens ! |
@xeniun Thanks for the link! I wonder why they bothered to add the IE9 comment instead of just adding That snippet indicates that the <script>
ga=function(){ga.q.push(arguments)};ga.q=[];ga.l=+new Date;
ga('create','UA-XXXX-Y','auto');ga('send','pageview')
</script>
<script src="https://www.google-analytics.com/analytics.js" async defer></script> |
@mathiasbynens Just out of curiosity, is the same if we reverse the sequences of the two scripts? |
@xeniun Yep, that doesn’t really matter. |
oh yeah. I'm on board with using I think we should be explicit with the |
@paulirish Like this? <script>
window.ga=function(){window.ga.q.push(arguments)};window.ga.q=[];window.ga.l=+new Date;
window.ga('create','UA-XXXX-Y','auto');window.ga('send','pageview')
</script>
<script src="https://www.google-analytics.com/analytics.js" async defer></script> Seems a bit much IMHO. I generally prefer making globals explicit in browser code by using |
Considering Paul's comment, is there any reason not to provide an unminified source of this snippet in the boilerplate? |
@mathiasbynens Can you open a pull request? Thanks! |
With this snippet, modern browsers use `async`, older browsers (i.e. IE8 & IE9) use `defer`. IE8 and IE9 lack `async` support but they have a broken implementation of `defer`. However, the brokenness doesn’t apply in this scenario since no scripts depend on GA in the way jQuery UI depends on jQuery. `async` is also not supported by the Android 2.3 browser, but that browser does have a preload scanner to make up for it. Once we drop support for IE8 and IE9, the `defer` attribute can be omitted. The only downside is that the snippet is not a pure JavaScript solution anymore, meaning it cannot be moved or concatenated into a `.js` file. On the other hand, no one seemed to be doing that anyway; everyone just inlines the snippet into the HTML. Ref. #1660 (comment)
@alrra Done in #1696. I haven’t added |
Thanks @mathiasbynens! 💜 Closing in favor of #1696. |
With this snippet, modern browsers use `async`, older browsers (i.e. IE8 & IE9) use `defer`. IE8 and IE9 lack `async` support but they have a broken implementation of `defer`. However, the brokenness doesn’t apply in this scenario since no scripts depend on GA in the way jQuery UI depends on jQuery. `async` is also not supported by the Android 2.3 browser, but that browser does have a preload scanner to make up for it. Once we drop support for IE8 and IE9, the `defer` attribute can be omitted. The only downside is that the snippet is not a pure JavaScript solution anymore, meaning it cannot be moved or concatenated into a `.js` file. On the other hand, no one seemed to be doing that anyway; everyone just inlines the snippet into the HTML. Ref. #1660 (comment)
With this snippet, modern browsers use `async`, older browsers (i.e. IE8 & IE9) use `defer`. IE8 and IE9 lack `async` support but they have a broken implementation of `defer`. However, the brokenness doesn’t apply in this scenario since no scripts depend on GA in the way jQuery UI depends on jQuery. `async` is also not supported by the Android 2.3 browser, but that browser does have a preload scanner to make up for it. Once we drop support for IE8 and IE9, the `defer` attribute can be omitted. The only downside is that the snippet is not a pure JavaScript solution anymore, meaning it cannot be moved or concatenated into a `.js` file. On the other hand, no one seemed to be doing that anyway; everyone just inlines the snippet into the HTML. Ref. #1660 (comment)
With this snippet, modern browsers use `async`, older browsers (i.e. IE8 & IE9) use `defer`. IE8 and IE9 lack `async` support but they have a broken implementation of `defer`. However, the brokenness doesn’t apply in this scenario since no scripts depend on GA in the way jQuery UI depends on jQuery. `async` is also not supported by the Android 2.3 browser, but that browser does have a preload scanner to make up for it. Once we drop support for IE8 and IE9, the `defer` attribute can be omitted. The only downside is that the snippet is not a pure JavaScript solution anymore, meaning it cannot be moved or concatenated into a `.js` file. On the other hand, no one seemed to be doing that anyway; everyone just inlines the snippet into the HTML. Ref. #1660 (comment)
With this snippet, modern browsers use `async`, older browsers (i.e. IE8 & IE9) use `defer`. IE8 and IE9 lack `async` support but they have a broken implementation of `defer`. However, the brokenness doesn’t apply in this scenario since no scripts depend on GA in the way jQuery UI depends on jQuery. `async` is also not supported by the Android 2.3 browser, but that browser does have a preload scanner to make up for it. Once we drop support for IE8 and IE9, the `defer` attribute can be omitted. The only downside is that the snippet is not a pure JavaScript solution anymore, meaning it cannot be moved or concatenated into a `.js` file. On the other hand, no one seemed to be doing that anyway; everyone just inlines the snippet into the HTML. Ref. #1660 (comment) Closes #1696.
With this snippet, modern browsers use `async`, older browsers (i.e. IE8 & IE9) use `defer`. IE8 and IE9 lack `async` support but they have a broken implementation of `defer`. However, the brokenness doesn’t apply in this scenario since no scripts depend on GA in the way jQuery UI depends on jQuery. `async` is also not supported by the Android 2.3 browser, but that browser does have a preload scanner to make up for it. Once we drop support for IE8 and IE9, the `defer` attribute can be omitted. The only downside is that the snippet is not a pure JavaScript solution anymore, meaning it cannot be moved or concatenated into a `.js` file. On the other hand, no one seemed to be doing that anyway; everyone just inlines the snippet into the HTML. Ref. h5bp/html5-boilerplate#1660 (comment) Closes #1696.
With this snippet, modern browsers use `async`, older browsers (i.e. IE8 & IE9) use `defer`. IE8 and IE9 lack `async` support but they have a broken implementation of `defer`. However, the brokenness doesn’t apply in this scenario since no scripts depend on GA in the way jQuery UI depends on jQuery. `async` is also not supported by the Android 2.3 browser, but that browser does have a preload scanner to make up for it. Once we drop support for IE8 and IE9, the `defer` attribute can be omitted. The only downside is that the snippet is not a pure JavaScript solution anymore, meaning it cannot be moved or concatenated into a `.js` file. On the other hand, no one seemed to be doing that anyway; everyone just inlines the snippet into the HTML. Ref. h5bp#1660 (comment) Closes h5bp#1696.
EDIT: it started to be a real mess in this post so i cleared it up
this is a shorter (and still safe) version of the google analytics snippet - 322 charcters against 346
it does exactly the same - except adding the script after the first script in the document rather than before it. only one function changed -
insertBefore
toappendChild
to eliminate the need for one of the parameters, all the rest is done by syntax manipulation ONLYthis is a bit more readable version (same code just added whitespace:
let go line by line:
new
(function (b, o, i, l) {
old(function(b,o,i,l,e,r)
not much to say we need less parameters
new
GoogleAnalyticsObject = l;
oldb.GoogleAnalyticsObject=l;
the window object is assumed if no object specified (except for conditional statements)
new
(b[l] = b[l] || function () {
oldb[l] || (b[l] = function () {
shorter syntax and we can use it 2 lines later
new
(b[l].q = b[l].q || []).push(arguments)}
old(b[l].q = b[l].q || []).push(arguments)}
no change here
new
).l = +new Date;
old);b[l].l = +new Date;
we use the functio0n it self as the object instead of referencing it
new
old
by changing to appendChild we do not need reference anymore and we declare anything inside the functions - using the original value and saving the need for a parameter
new
(window, document, 'script', 'ga'));ga('create', 'UA-XXXXX-X', 'auto');ga('send', 'pageview');
old(window, document, 'script', 'ga'));ga('create','UA-XXXXX-X','auto');ga('send','pageview');
also the same
I've checked this script with google analytics debugger, also with multiple trackers
it works (no reason why not)
@mathiasbynens - feel free to update your article about it if you like