Best practises for event activity tracking in the web
Tags: analytics, javascript
Published: 2021-08-08 07:36:16

---
title: Best practises for event activity tracking in the web
published: true
description: 
tags: Analytics, JavaScript
cover_image: https://optinmonster.com/wp-content/uploads/2019/07/google-analytics-wordpress-2.png
---
Dealing with user activity in web applications is almost always an afterthought. To that, we should also understand that this is not something new and has been happening for quite a long time by major platforms and websites out there. 
I am no judge to say if it is a good practice or not, but as an engineer, I will try to note down the recent development in this space over the years. And, moreover, if you are tasked to do something similar for your new app, how you can go about doing it.

## Let's talk about the basics
Our primary goal is to reliable track user's activity without affecting the application performance. Now, what is categorized as user activity is something we will address in a future blog, but regardless of the granularity of the data what is our concern at the moment is how we collect metrics data from a technical perspective.


Overarchingly, we have two kinds of data being passed around the server and browser. Namely, analytical data and transactional data. Our first step is to identify which request falls under which category. This is done to prevent us from degrading the performance of our application by prioritizing one over the other.


Once we have segregated the analytical requests, it is time for us to find the best possible way to communicate this data back to our servers. Few recommendations in terms of collection and transport of this data are given below:

## Using Pixels
In some situations, third-party scripts can be replaced with image or iframe "pixels". Compared to their script-based counterparts, these pixels may support less functionality; however, because there is no JavaScript execution, they are also the most performant and secure type of tag. Pixels have a very small resource size (less than 1 KB) and do not cause layout shifts.

Pixels have been popular for quite some time now as, during the old days, it was considered one of the cheapest and the most reliable options out there to send HTTP web requests to a backend where the client doesn't need to consume the response. 

There is nothing wrong with consuming pixels, but my suggestion in case you are building your own  tooling, to consider using sendBeacon and fetch keep-alive as mentioned below

## Using sendBeacon() API
The navigator.sendBeacon API sends a small amount of data over the wire to a web server in an asynchronous manner. It is intended to be used for sending analytics and metric data. This API helps avoid problems with legacy XMLHTTPRequest usage for sending analytics data.

This API can be used for sending data where the server's response does not matter. 

```javascript
const url = "https://nvgs.com/analytics";
const data = JSON.stringify({
    event: "checkout",
    time: performance.now()
});

navigator.sendBeacon(url, data);
```

This API only supports POST requests and moreover does not support any custom header. But the good news is, it is supported by all modern browsers. This API ensures that data does not affect the performance of your application or next page as it does not block code execution during page unload. You can use the following script to send data at the page unload without affecting browser behavior.

```javascript
document.addEventListener('visibilitychange', function logData() {
  if (document.visibilityState === 'hidden') {
    navigator.sendBeacon('/log', analyticsData);
  }
});
```

## Using fetch() keep-alive  
You can also use the popular fetch() API to send analytics data, but make sure to set the keep-alive flag to true in order to make non-blocking requests for event-reporting data. The keep-alive flag is supported by fewer browsers than the sendBeacon API so usage of this API is not recommended. 
```javascript
const url = "https://nvgs.com/analytics";
const data = JSON.stringify({
  event: "checkout",
  time: performance.now()
});

fetch(url, {
    method: 'POST',
    body: data,
    keepalive: true
});
```