matomo-org / matomo

Empowering People Ethically with the leading open source alternative to Google Analytics that gives you full control over your data. Matomo lets you easily collect data from websites & apps and visualise this data and extract insights. Privacy is built-in. Liberating Web Analytics. Star us on Github? +1. And we love Pull Requests!
https://matomo.org/
GNU General Public License v3.0
19.71k stars 2.62k forks source link

Performance enhancement: Return HTTP 204 instead of GIF for JavaScript tracking #6577

Closed da2x closed 9 years ago

da2x commented 9 years ago

As performance is now a priority, I’d like to suggest something that should be investigated

Piwik’s gif image is very small. However, no content (HTTP/1.1 204 No Content) is even smaller. Saves some 55 bytes on the server responds. Not having to serve and decode the image data will speed up outputTransparentGif in Tracker.php for high-traffic instances as well.

For JavaScript tracking, return HTTP/1.1 204 No Content (no body!) instead of the transparent gif file. The latter method should still be used the <noscript><img>-tracking as 204-ing an img is untested territory. It would at least require to set the height and width on the tracking img itself.

sgiehl commented 9 years ago

We would need to investigate if all browsers can handle that. Maybe some older browsers might show an broken image symbol if such an header is returned...

da2x commented 9 years ago

@sgiehl, the JavaScript tracking method don’t use the requested image anywhere, correct? Its just requested and never actually injected into the document. Returning 204 should make no difference other than a smaller acknowledgement-of-receipt payload. Piwik could actually send back a picture of a honey badger for all the difference it would do. Well, the performance would suffer if we sent all that unnecessary data.

The noscript tracking method (<1% of users, right?) should still use the gif method to avoid this (as I said somewhat unclearly in the third paragraph in my initial comment).

mattab commented 9 years ago

Thanks for the suggestion! you're right the image is not copied in the DOM so we could make the change for the JavaScript Tracking API requests only and leave the 1*1 gif for <noscript> requests.

dareid commented 9 years ago

Returning an image instead of a 204 also impacts piwik's use in chrome apps. Images are not allowed to be obtained from the web directly and hence using the piwik javascript tracker currently throws security errors. (further reading : https://developer.chrome.com/apps/app_external#external)

mattab commented 9 years ago

@dareid thanks this makes me think more of this issue. Maybe it would not be a performance improvement so much as a fixing a bug on Chrome apps? Do you know how the problem with chrome apps can be reproduced?

(basically if it's a bug then we would schedule it higher priority)

dareid commented 9 years ago

Sure please see https://gist.github.com/dareid/eaf87732c5f79e0dfef1. If you download the files and load that into chrome as an unpacked extension you will see the error in the dev console.

tsteur commented 9 years ago

Should we add a URL parameter in JavaScript so that we know the request is from piwik.js? We are not the only consumer of this API and some might actually do track via an image etc.

Maybe we can add a URL parameter like no_response=1? This would also make it easier to keep the tests easy as it allows us to still test for the gif and it allows other people to use this as well. Eg I'd like to use it in Mobile App

cybernet commented 9 years ago

+1

da2x commented 9 years ago

You could probably see its a JS request without changing the code. There are likely to be some HTTP header information that could be used. POST vs GET. I thought the gif noscript tracking only requested one path instead of a path with query, for example. Could be some AJAXy header also, for example.

tsteur commented 9 years ago

Headers could get lost in proxies etc. and JS can use both POST and GET.

The noscript image solution sends a URL like this //piwik.php?idsite=1. Of course I could test whether only the idsite is set and then still return an image, a 204 header otherwise. This would break the API for many users though who might expect an image and we don't want to break anything. It would be also a bit confusing / not predictable etc whether they'd get an image or not. Also we might want to send more parameters using the noscript solution in the future.

We could maybe send a header to not return an image and if the header gets lost it doesn't matter so much as the worst thing that happens would be sending an image that is not used. But then it is a bit simpler to send a URL parameter for this and people could use it anywhere, even where it is not possible to set a header. Also while it doesn't matter for the browser whether we send back a 204 or an image it might matter somewhere else.

mattab commented 9 years ago

+1 for a new parameter, it's easy to understand & document

tsteur commented 9 years ago

Created issues to use it in iOS & Android SDK as well. Documented it in Tracker API reference. Not sure if something is missing! Will close it for now.

New URL parameter in Tracking API is send_image=0

mattab commented 9 years ago

:+1: