Architecture: Javascript event tracking in browser - javascript

I want to make a custom tracking system for web events. I have looked into multiple per-excsiting systems, but I want something terribly simple - yet very accurate.
I want to be able to track the following:
Page view even
Time on that page
or:
Video started playing event
Time of video watched
My first initial thought was to do a simple javascript reporting back to the server, but what happens if the user closes the window? How do I know they stopped viewing? And how can I get accurate measurements down to 1/10th of a second? So I thought of a websocket solution, as it know when a user has discounted. I ended up with Socket.io, but I want to make sure there is no better or smarter way to achieve this?
How would you approach his challenge? What is the smartest way to engineer this?

A Websocket connection which reports back to the server frequently was my first thought as well, but if you send 10 messages every second, even that might be too much for a websocket, especially when connectivity isn't top-notch.
Since the server doesn't require the information absolutely immediately, consider batching requests instead - save/update the information into Local Storage every 0.1 seconds, but don't send it to the server then - instead, every 30 or 60 seconds, or on pageload, take the current data in Local Storage and send it to the server, and clear Local Storage so that the next request a minute from now doesn't send duplicate data.

Related

Implement a timer for user logout after timeout in the frontend

I was wondering what the best way of implementing a timer in the frontend would be.
The idea is to notify the user after 13 minutes of inactivity (= not made a request to the backend) that he will be logged out in 2 minutes.
My first attempt was to just use a Timer which is executed every second (I am doing this with Flutter web but it shouldn't make a difference) and counts down from 15 minutes.
Then we tested this internally and noticed that the Browser somehow stops JavaScript execution if the user switches to a different tab for a long time or if the computer goes into stand by such that the timer stops.
We already have a session timeout after 15 minutes from the backend, this is just to make the user experience better.
How would this be correctly implemented?
For short, I think it's impossible for only using frontend
As you examine, the javascript code will be stop whenever switching tab or close tab, computer stands by. So that it will not be good to use a timeout or something like that.
I used an idea before but not implemented it yet because I switched to simpler idea with sessionStorage. But you could see and somehow success with it: when last request is made, created a cookie with expire time is 13 minutes. If next request is made, clear old cookie and add a new cookie with 13 minutes too. If the request will not made during 13 minutes, when cookie expire, fire a event to annouce to user. To listening cookie change, I think there are a lot solutions out there. But for me, this idea is not so good so I forgot it.
If you can use a nodejs backend, you could try to use Server Send Event - SSE. This will create one-way sending data. Therefore you can stream a chunk of data. And the frontend will listen that streaming and decide whether to annouce to user.

Best way to keep the data up-to-date when dealing with web socket async request

I'm seeking the best way to keep the data up-to-date when dealing with web socket async requests, especially data that contain time information.
I have a dashboard, when I logged/pressed feed I updated the nextFeed time to feedingInterval + the current logged time.
feedingInterval = 2 hrs
I used to do form submit, and page refresh.
Also, I used to do location.reload() every 1 minute to keep my nextFeed time up-to-date when my user opened up the link on a machine connected to a TV.
nextFeed time always up to date, worse case there is 1 mn lagged.
NOW
To enhance the UX:
I don't use form submit anymore, so no page refresh, I use Ajax POST to a web socket route to broadcast to all my devices. When I receive any push notifications from Pusher Cloud, I update the DOM live dynamically on all my devices.
Issue
I used to refresh my page every 1 minute, since I didn't do ( location.reload(); ) anymore. My feeding time will become stale (not up-to-date).
Current solution:
I created an API to get the nextFeed time, called it every 5 seconds, and update DOM every 5 seconds. I notice my browser seem very hot since, maybe due too much requests in a minute.
Then you might say/think... just called every minute then ...
But ... If I make a call every one 1 minute then my users wont' have up-to-date information which defeats the purpose of me doing the websocket in the first place.
What should I do to have the best UX, but not too compromise my performance?
https://www.bunlongheng.com/baby/5db53c4c-5be4-4aa2-b9f6-b564acb871ac?code=d3s!gn

Onunload, onbeforeunload - guidance requested

I have a web server that generates questions for students of a particular subject. The web server needs to keep track of how much time each student has spent on a particular set of questions.
The web pages have a "Finished" button, which, when pressed, causes statistics to be sent to server.
However, I also want the web browser to send statistics if the student navigates away from the page or closes the browser window without pressing "Finished".
For this purpose, I have planned to have "onunload" or "onbeforeunload" send an Ajax request to the server with the relevant information. But apparently different browsers do not fully support these events, and also there are restrictions on what can be done in the event handlers. And, of course, I don't want the browse to freeze if the communication with the server fails.
So, I need some advice on the best way to do this.
If I wanted to be sure to handle all the "special events" I would send tick 'requests' from the webpage to the server. Granularity depends on the tracking requirements, the load, and whether it is an intranet or internet application; can be some seconds or even a minute. So you are tracking the time spent on the page even if the browser/os/network crashes.
The best way to implement is, is to use period updates. This will pretty much guarantee you have some relevant data when the user disconnects in any way.
An implementation is pretty trivial, all tough you might have to refactor some of your logic to send out period updates instead of everything at once.
function sendStatistics()
{
// ajax and what not
}
setInterval(function(){
sendStatistics();
}, 1000);
An other way to make it work is to make your ajax call in beforeunload and make it synchronous. This will freeze the browser for duration of the call, and will also only work when navigating away or closing the browser, i don't recommend this.

Save HTML5 video currentTime before user leaves or closes page

I would like to save the position of HTML5 video's currentTime to the database when user leaves a web page. It seems like window.onbeforeunload is not a reliable way to do it (not to mention it gives an undesirable popup window!). Is there a better way to do this?
I can't think of anything other than saving the position to the server periodically. But that seems wasteful resource/bandwidth wise. Netflix seems to do a good job at remembering your last viewed position. How would they be able to achieve that reliably? Low-level server-side C/C++ code maybe?
There are various ways to save such things:
Locally (for the same domain)
beforeunload
This gives you the possibility to cancel the unload event if you desire. However, the popup is optional.
unload
This event can't be cancelled but you still have full access to all nodes and JavaScript variables. So you can do final cleanup/save then if canceling is not wanted. You can use whichever saving method you like, e.g. document.cookie or window.localStorage.
window.onunload = function () {
window.localstorage[myVideo.currentTime] = document.getElementById("myVid").currentTime;
}
If you can handle the fact that you can only process cookies and localStorage when the user comes back to your site. I think this approach would be perfect. You simply save the current time and on the users next visit you'll get the updated information.
On the Backend
If you really need to save that information to your backend you can try some other things.
DB polling
Depending on you accuracy needs you could send an ajax request every 10 - 20 seconds to update the playback time. If you just include the video id and current time, the request is so small it shouldn't have an effect on performance. However keep in mind that if you have lots of domain cookies it might increase the size of requests tremendously and your 500 byte payload might come with a 5kB header.

How to update asynchron pages upon event from other client?

I'm currently fooling around with AJAX. Right now, I created a Markdown previewer that updates on change of a textarea. (I guess you know that from somewhere... ;-) ).
Now, I'm trying to figure out, how to update a page upon an event is fired from another client. So to say an asynchron message board. A user writes something, an event is called, the post is written.
But on the other clients' pages, the new post is of course not yet available until they reload and get the updated list of posts from the database.
Now, how can you get this to work asynchronously? So in that moment when one client does something, the other clients all get to know that he did something?
I don't think this can be done completely in AJAX, but I also have no idea whatsoever how to implement this on server-side, as it would require a page reload to inform the other clients of the event.
I'm thinking of creating a file or database entry that hashes the current state of data. Whenever a client loads the page, he saves this hash. Then, a timer (does this exist in JavaScript?) checks for the hash every few seconds.
As soon as anyone changes the databse, the hash is recalculated. If the script sees that the hash was changed and is different to the one saved, it reloads the contents form the database and saves the new hash.
Is that even going to work?
Polling that is light as possible is really the best solution here. Even if you did use a socket or something... That's still basically a live connection waiting around that will likely have to poll itself (albeit in a more effecient way).
20 queries in 10 minutes that have responses like {"updates":false} shouldn't even be putting a dent in your application. I mean imagine someone browsing your site requesting 20 pages and the related images/scripts/etc (even if some caching is involved), there could easily be hundreds of requests requiring all sorts of wasted database queries to information to be displayed on the page they don't actually care about.
You could use polling. For example each client might be sending continuous AJAX requests to the server say each 30 seconds to see if new posts are available and if yes, show them:
setInterval(function() {
// TODO: Send an AJAX request here to the server and fetch new posts.
// if new posts are available update the DOM
}, 30 * 1000);
On the other hand when someone decides to write a new post you send an AJAX (or not AJAX) request to the server to store this post in the database.
Another less commonly used approach is the concept of Comet and the HTML 5 WebSockets implementation which allow the clients to be notified by the server of changes using push.

Categories