4

Piwik (analytics software), works by including a small script just before the </body>:

<script type="text/javascript">
  var _paq = _paq || [];
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="//piwik.example.com";
    _paq.push(['setTrackerUrl', u+'piwik.php']);
    _paq.push(['setSiteId', 1]);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
  })();
</script>

This script will then include piwik.js (basically this script) from your piwik installation on the page. piwik.js records a couple of things (screen size, ip, etc.) and sends that to your piwik installation in a GET request, to register the pageview.

Now I don't understand why you would not just include piwik.js on your page straightaway. Why go through the trouble of fetching it from a separate location when you can just concatenate and minify it with the rest of your scripts?

It is possible to host piwik.js on a cdn (see here and here), so I'm wondering why you wouldn't skip that step and concatenate it with the rest of your scripts and optimize from there?


Google analytics does the same thing I believe, so the answer doesn't need to be specific to Piwik as long as it applies to both.

1 Answers1

3

This is to prevent the piwik.js file from blocking the rendering of the page. As you say, the snippet provided by Google Analytics works in much the same way. Steve Souders has a good write-up on the many benefits at http://www.stevesouders.com/blog/2009/12/01/google-analytics-goes-async/.

See also: http://googlecode.blogspot.nl/2009/12/google-analytics-launches-asynchronous.html

The second half of the snippet provides the logic that loads the tracking code in parallel with other scripts on the page. It executes an anonymous function that dynamically creates a element and sets the source with the proper protocol. As a result, most browsers will load the tracking code in parallel with other scripts on the page, thus reducing the web page load time.

redburn
  • 542
  • 4
  • 24
  • Yes, I see that it sets an `async` attribute. But why not include a script with an `async` attribute directly then (or even better, include the code last and concatenate and minify with the rest)? I don't see any reason to load it from a separate location just in order to do that.. – vkjb38sjhbv98h4jgvx98hah3fef Dec 19 '14 at 13:13
  • 2
    All that I could say in favor of this method so far is that when Piwik is upgraded (or the google tracking code is), the script will automatically fetch the updated version, instead of relying on the admin to update the tracking code. – vkjb38sjhbv98h4jgvx98hah3fef Dec 19 '14 at 13:15
  • 1
    As noted in the Google blog post, dynamically inserting the script into the page has the same effect as the `async` attribute. I believe it's a workaround for the lack of support for `async` in older browser like Internet Explorer <= 9. Also, the Google Analytics snippet allows you to begin recording data before ga.js is even loaded, and Piwik probably works in much the same way. – redburn Dec 19 '14 at 13:21
  • Ok, so including piwik.js as the last script (and minifying and concatenating it) before the `

    ` would: 1. prevent it from being loaded in parallel 2. prevent automatic version control 3. Maybe delay the recording of data. Other than that, there are no downsides? Because for me the server that serves piwik.js is the bottleneck, so I think that for me speed would improve when concatenating piwik.js with my other scripts, and I would be fine with less version control and delayed recording.

    – vkjb38sjhbv98h4jgvx98hah3fef Dec 19 '14 at 13:31
  • If that'd work (note that the snippet sets a number of required variables before loading piwik.js), the benefit in terms of performance, if any, would probably be negligible. How is "the server that serves piwik.js" a bottleneck? – redburn Dec 19 '14 at 13:40
  • By the way, in [this discussion](https://github.com/html5rocks/www.html5rocks.com/issues/856) it's been said that only when you surpass 125kB you'll see performance improvements for async loading over concatenating. – vkjb38sjhbv98h4jgvx98hah3fef Dec 19 '14 at 13:40
  • Yes, I would include the parts of the code that are required for the correct execution of piwik.js of course. And my analytics server is not behind a cdn (for stupid reasons) and my website server is. So serving it from my website would be faster because of the cdn. So in that specific use case it would make sense right? – vkjb38sjhbv98h4jgvx98hah3fef Dec 19 '14 at 13:42
  • Sounds like what you really want is to use different domains for piwik.js and for piwik.php, so that JavaScript is loaded from your CDN but the data is sent to your analytics server. What if you set `var u="//www.example.com";` (your webserver or cdn) and `_paq.push(['setTrackerUrl', '//piwik.example.com/piwik.php']);` (your analytics server)? – redburn Dec 19 '14 at 14:43
  • Sort of. I've tested a couple of different configurations, and the fastest option for me was modifying the snippet that sets the necessary variables to prevent it from creating a script element (whilst still creating `_paq`), and just concatenating `piwik.js` after that, and then minifying the whole shebang. About a 20% speed increase. – vkjb38sjhbv98h4jgvx98hah3fef Dec 19 '14 at 16:18