detecting-inactive-users

Most of the time you don’t really care about whether a user is actively engaged or temporarily inactive on your application. Inactive, meaning, perhaps they got up to get a drink of water, or more likely, changed tabs to do something else for a bit. There are situations, though, when tracking the user activity and detecting inactive-ness might be handy.

Let’s think about few examples when you just might need that functionality:

  • tracking article reading time
  • auto saving form or document
  • auto pausing game
  • hiding video player controls
  • auto logging out users for security reasons

I recently encountered a feature that involved that last example, auto logging out inactive users for security reasons.

Why should we care about auto logout?

Many applications give users access to some amount of their personal data. Depending on the purpose of the application, the amount and the value of that data may be different. It may only be user’s name, but it may also be more sensitive data, like medical records, financial records, etc.

There are chances that some users may forget to log out and leave the session open. How many times has it happened to you? Maybe your phone suddenly rang, or you needed to leave immediately, leaving the browser on. Leaving a user session open is dangerous as someone else may use that session to extract sensitive data.

One way to fight this issue involves tracking if the user has interacted with the app within a certain period of time, then trigger logout if that time is exceeded. You may want to show a popover, or perhaps a timer that warns the user that logout is about to happen. Or you may just logout immediately when inactive user is detected.

Going one level down, what we want to do is count the time that’s passed from the user’s last interaction. If that time period is longer than our threshold, we want to fire our inactivity handler. If the user performs an action before the threshold is breached, we reset the counter and start counting again.

This article will show how we can implement such an activity tracking logic based on this example.

Step 1: Implement tracking logic

Let’s implement two functions. The first will be responsible for resetting our timer each time the user interacts with the app, and the second will handle situation when the user becomes inactive:

  • resetUserActivityTimeout – This will be our method that’s responsible for clearing the existing timeout and starting a new one each time the user interacts with the application.
  • inactiveUserAction – This will be our method that is fired when the user activity timeout runs out.
let userActivityTimeout = null;

function resetUserActivityTimeout() {
  clearTimeout(userActivityTimeout);
  userActivityTimeout = setTimeout(() => {
    inactiveUserAction();
  }, INACTIVE_USER_TIME_THRESHOLD);
}

function inactiveUserAction() {
  // logout logic
}

OK, so we have methods responsible for tracking the activity but we do not use them anywhere yet.

Step 2: Tracking activation

Now we need to implement methods that are responsible for activating the tracking. In those methods, we add event listeners that will call our resetUserActivityTimeout method when the event is detected. You can listen on as many events as you want, but for simplicity, we will restrict that list to a few of the most common ones.

function activateActivityTracker() {
  window.addEventListener("mousemove", resetUserActivityTimeout);
  window.addEventListener("scroll", resetUserActivityTimeout);
  window.addEventListener("keydown", resetUserActivityTimeout);
  window.addEventListener("resize", resetUserActivityTimeout);
}

That’s it. Our user tracking is ready. The only thing we need to do is to call the activateActivityTracker on our page load.

We can leave it like this, but if you look closer, there is a serious performance issue with the code we just committed. Each time the user interacts with the app, the whole logic runs. That’s good, but look closer. There are some types of events that are fired an enormous amount of times when the user interacts with the page, even if it isn’t necessary for our tracking. Let’s look at mousemove event. Even if you move your mouse just a touch, mousemove event will be fired dozens of times. This is a real performance killer. We can deal with that issue by introducing a throttler that will allow the user activity logic to be fired only once per specified time period.

Let’s do that now.

Step 3: Improve performance

First, we need to add one more variable that will keep reference to our throttler timeout.

let userActivityThrottlerTimeout = null

Then, we create a method that will create our throttler. In that method, we check if the throttler timeout already exists, and if it doesn’t, we create one that will fire the resetUserActivityTimeout after specific period of time. That is the period for which all user activity will not trigger the tracking logic again. After that time the throttler timeout is cleared allowing the next interaction to reset the activity tracker.

userActivityThrottler() {
  if (!userActivityThrottlerTimeout) {
    userActivityThrottlerTimeout = setTimeout(() => {
      resetUserActivityTimeout();

      clearTimeout(userActivityThrottlerTimeout);
      userActivityThrottlerTimeout = null;
    }, USER_ACTIVITY_THROTTLER_TIME);
  }
}

We just created a new method that should be fired on user interaction, so we need to remember to change the event handlers from resetUserActivityTimeout to userActivityThrottler in our activate logic.

activateActivityTracker() {
  window.addEventListener("mousemove", userActivityThrottler);
  // ...
}

Bonus: Let’s reVue it!

Now that we have our activity tracking logic implemented let’s see how can move that logic to an application build with Vue. We will base the explanation on this example.

First we need to move all variables into our component’s data, that is the place where all reactive props live.

export default {
  data() {
    return {
      isInactive: false,
      userActivityThrottlerTimeout: null,
      userActivityTimeout: null
    };
  },
// ...

Then we move all our functions to methods:

// ...
  methods: {
    activateActivityTracker() {...},
    resetUserActivityTimeout() {...},
    userActivityThrottler() {...},
    inactiveUserAction() {...}
  },
// ...

Since we are using Vue and it’s reactive system, we can drop all direct DOM manipulations i.(i.e. document.getElementById("app").innerHTML) and depend on our isInactive data property. We can access the data property directly in our component’s template like below.

Last thing we need to do is to find a proper place to activate the tracking logic. Vue comes with component lifecycle hooks which are exactly what we need — specifically the beforeMount hook. So let’s put it there.

// ...
  beforeMount() {
    this.activateActivityTracker();
  },
// ...

There is one more thing we can do. Since we are using timeouts and register event listeners on window, it is always a good practice to clean up a little bit after ourselves. We can do that in another lifecycle hook, beforeDestroy. Let’s remove all listeners that we registered and clear all timeouts when the component’s lifecycle comes to an end.

// ...
  beforeDestroy() {
    window.removeEventListener("mousemove", this.userActivityThrottler);
    window.removeEventListener("scroll", this.userActivityThrottler);
    window.removeEventListener("keydown", this.userActivityThrottler);
    window.removeEventListener("resize", this.userActivityThrottler);
  
    clearTimeout(this.userActivityTimeout);
    clearTimeout(this.userActivityThrottlerTimeout);
  }
// ...

That’s a wrap!

This example concentrates purely on detecting user interaction with the application, reacting to it and firing a method when no interaction is detected within specific period of time. I wanted this example to be as universal as possible, so that’s why I leave the implementation of what should happened when an inactive user it detected to you.

I hope you will find this solution useful in your project!

133 comments

  1. Do you have a spam problem on this blog; I also am a blogger, and I was wondering your situation; we have developed some nice practices and
    we are looking to swap solutions with others, why not shoot me an e-mail if interested.

  2. Its like you read my thoughts! You appear to grasp a lot about this, like you wrote the ebook in it or
    something. I feel that you can do with some % to force the message house a little bit, however instead of that, this is
    fantastic blog. A great read. I’ll definitely be back.

  3. I think this is one of the most important info for me.
    And i’m glad reading your article. But want to remark on some
    general things, The website style is ideal, the
    articles is really great : D. Good job, cheers

  4. My brother recommended I might like this web site.
    He was totally right. This post actually made my day.
    You cann’t imagine simply how much time I had spent for this information! Thanks!

  5. Hi there, i read your blog occasionally and i own a similar one and i was just wondering if you get a
    lot of spam comments? If so how do you reduce it, any plugin or anything you can advise?
    I get so much lately it’s driving me insane so any support is very much appreciated.

  6. Hi are using WordPress for your blog platform? I’m new to the blog
    world but I’m trying to get started and set up my own. Do you need any coding knowledge to make your own blog?
    Any help would be really appreciated!

  7. I’ve been browsing online more than three hours today, yet
    I never found any interesting article like yours. It is pretty
    worth enough for me. Personally, if all website
    owners and bloggers made good content as you did, the web will be much more
    useful than ever before.

  8. It’s in reality a nice and useful piece of info. I’m satisfied that you just shared
    this helpful info with us. Please keep us informed like this.
    Thank you for sharing.

  9. My brother suggested I may like this blog. He was entirely right.
    This publish truly made my day. You can not consider just
    how much time I had spent for this information! Thank you!

  10. Ahaa, its nice discussion regarding this post at this place at this website, I have
    read all that, so at this time me also commenting here.

  11. I loved as much as you will receive carried out right here.

    The sketch is attractive, your authored material stylish.
    nonetheless, you command get bought an shakiness over that you
    wish be delivering the following. unwell unquestionably
    come more formerly again since exactly the same nearly a lot often inside case you shield this increase.

  12. Do you mind if I quote a few of your articles as long as I provide credit and
    sources back to your weblog? My website is in the very same area of interest as yours and my visitors would certainly benefit from a lot
    of the information you provide here. Please let me know if this alright with you.
    Many thanks!

  13. Good day! I could have sworn I’ve visited your blog before but after going through
    some of the articles I realized it’s new
    to me. Anyways, I’m certainly delighted I came across
    it and I’ll be bookmarking it and checking back frequently!

  14. Hi there I am so thrilled I found your web site, I really found you by mistake, while I was browsing on Google for something else,
    Anyways I am here now and would just like to say many
    thanks for a marvelous post and a all round thrilling
    blog (I also love the theme/design), I don’t have time to go through it all at the minute but I have saved it and also added in your RSS
    feeds, so when I have time I will be back to read a great
    deal more, Please do keep up the awesome job.

  15. Hi there just wanted to give you a brief heads up and let you know a few of the images aren’t loading correctly.
    I’m not sure why but I think its a linking issue.
    I’ve tried it in two different web browsers and both show the same results.

  16. A fascinating discussion is worth comment.

    I think that you should publish more about this
    subject matter, it might not be a taboo subject but typically
    people don’t speak about these issues. To the next! Kind regards!!

  17. My brother recommended I might like this website.
    He was totally right. This post actually made my day.

    You cann’t imagine just how much time I had spent for this
    info! Thanks!

  18. Hello there! I could have sworn I’ve been to this site before
    but after checking through some of the post I realized it’s new to me.
    Anyhow, I’m definitely delighted I found it and I’ll be book-marking and checking back frequently!

  19. Today, I went to the beach front with my children. I found a sea
    shell and gave it to my 4 year old daughter and said “You can hear the ocean if you put this to your ear.”
    She placed the shell to her ear and screamed.

    There was a hermit crab inside and it pinched her ear. She never wants to go back!
    LoL I know this is totally off topic but I had to tell someone!

  20. My developer is trying to convince me to move to .net from PHP.

    I have always disliked the idea because of the costs.
    But he’s tryiong none the less. I’ve been using WordPress on a
    number of websites for about a year and am concerned about switching to another platform.
    I have heard excellent things about blogengine.net. Is there a way I
    can import all my wordpress content into it? Any help would be really appreciated!

  21. This is the right website for everyone who would like to find out about this topic.

    You know a whole lot its almost hard to argue with you (not
    that I personally would want to…HaHa). You certainly put a fresh
    spin on a subject which has been written about for many years.
    Wonderful stuff, just wonderful!

  22. Howdy would you mind letting me know which web host you’re utilizing?
    I’ve loaded your blog in 3 different web browsers and I must say this
    blog loads a lot quicker then most. Can you suggest a good internet hosting provider at a reasonable price?
    Thank you, I appreciate it!

  23. Fantastic items from you, man. I have take into accout your stuff previous to and you’re simply extremely wonderful.

    I actually like what you have got here, certainly like what you’re stating and the
    way in which by which you say it. You are making it entertaining and you continue to
    take care of to keep it wise. I can’t wait to read much more from you.
    That is actually a terrific site.

  24. Thank you for any other wonderful post. Where else may anyone get that kind of info in such
    a perfect means of writing? I have a presentation next week,
    and I’m on the search for such info.

  25. I simply could not leave your web site prior to suggesting that I
    actually enjoyed the standard information an individual supply on your visitors?
    Is going to be back continuously in order to inspect new posts

  26. Just want to say your article is as amazing.
    The clearness in your post is simply excellent and
    i could assume you are an expert on this subject. Fine with
    your permission allow me to grab your feed to keep updated with forthcoming post.

    Thanks a million and please carry on the gratifying work.

  27. Greate post. Keep posting such kind of info on your blog.

    Im really impressed by your site.
    Hello there, You’ve done an incredible job.
    I will definitely digg it and individually recommend to
    my friends. I’m sure they’ll be benefited from this website.

  28. Hello! I know this is kinda off topic but I’d figured I’d ask.
    Would you be interested in exchanging links or maybe guest authoring a blog article or vice-versa?

    My blog addresses a lot of the same subjects as yours and I
    think we could greatly benefit from each other. If you
    might be interested feel free to shoot me an e-mail.
    I look forward to hearing from you! Fantastic blog
    by the way!

  29. I’m not that much of a online reader to
    be honest but your sites really nice, keep it up! I’ll go ahead and bookmark your
    site to come back in the future. All the best

  30. Hey! Quick question that’s entirely off topic.
    Do you know how to make your site mobile friendly?
    My site looks weird when viewing from my iphone4.
    I’m trying to find a template or plugin that
    might be able to correct this issue. If you have any suggestions,
    please share. With thanks!

  31. Fantastic items from you, man. I have have in mind your stuff prior to and you are
    simply too fantastic. I really like what you’ve bought
    right here, certainly like what you’re stating and the way during which
    you assert it. You make it entertaining and you continue to care for to
    stay it smart. I can’t wait to learn much more from you. That is really a wonderful web site.

  32. Thanks , I’ve just been searching for info about this topic for a while
    and yours is the best I’ve found out till now. But, what in regards
    to the bottom line? Are you positive concerning
    the source?

  33. When I originally commented I clicked the “Notify me when new comments are added” checkbox and now each time a comment is added I get several e-mails with the same comment.
    Is there any way you can remove people from that service? Thank you!

  34. Does your blog have a contact page? I’m having problems locating it but,
    I’d like to shoot you an e-mail. I’ve got some ideas for your blog you might be interested in hearing.
    Either way, great blog and I look forward to seeing it develop over time.

  35. Greate pieces. Keep writing such kind of info on your page.
    Im really impressed by it.
    Hey there, You have performed an incredible job.

    I will definitely digg it and personally recommend to my friends.
    I’m confident they will be benefited from this website.

  36. hello there and thank you for your information –
    I have definitely picked up something new from right here.
    I did however expertise some technical issues using this
    website, as I experienced to reload the website lots of
    times previous to I could get it to load properly. I had been wondering if your
    web host is OK? Not that I am complaining, but sluggish loading instances times will sometimes
    affect your placement in google and can damage your quality score if advertising and marketing with Adwords.
    Well I’m adding this RSS to my e-mail and could look out for
    a lot more of your respective intriguing content. Make sure you update this again very soon.

  37. It’s really a great and helpful piece of information. I’m happy that you just shared this helpful information with
    us. Please keep us informed like this. Thanks for sharing.

  38. After I initially commented I seem to have clicked on the -Notify
    me when new comments are added- checkbox and now each time a comment is added I
    recieve four emails with the exact same comment. There has to be a way
    you can remove me from that service? Thanks!

  39. Hi there, I discovered your web site by way of Google at the same time
    as looking for a similar subject, your web site came up, it looks good.
    I’ve bookmarked it in my google bookmarks.

    Hello there, simply was aware of your weblog thru Google, and located
    that it is truly informative. I’m gonna be careful for brussels.
    I will be grateful if you proceed this in future. Many other
    folks will be benefited out of your writing. Cheers!

  40. I am not sure where you’re getting your info,
    but good topic. I needs to spend some time learning much more
    or understanding more. Thanks for magnificent info I was looking
    for this information for my mission.

  41. all the time i used to read smaller content which also clear their
    motive, and that is also happening with this post which I am reading at this
    place.

  42. Hey There. I found your blog using msn. This is a really well written article.
    I will make sure to bookmark it and come back to read more of your useful information. Thanks for the post.

    I’ll certainly return.

  43. Excellent blog you have here but I was wondering if you knew of any message boards that
    cover the same topics talked about in this article? I’d really
    like to be a part of online community where I can get advice from other knowledgeable people that share the same interest.

    If you have any suggestions, please let me know.
    Thanks!

  44. Thank you for another informative blog. Where else may I am getting that type of info written in such a perfect approach?
    I’ve a mission that I’m just now operating on, and I’ve
    been at the glance out for such information.

  45. After looking at a handful of the articles on your
    website, I honestly appreciate your technique of writing a blog.

    I saved as a favorite it to my bookmark website list and
    will be checking back soon. Please visit my website too and let me know what you
    think.

  46. Nice post. I used to be checking continuously this weblog and
    I’m impressed! Very helpful information specifically the remaining section 🙂 I care for such
    information much. I used to be seeking this particular information for a very long time.
    Thank you and good luck.

  47. Definitely imagine that that you said. Your favourite
    reason seemed to be on the internet the easiest factor
    to understand of. I say to you, I definitely get irked at the same time as other people think about concerns that they plainly
    don’t understand about. You managed to hit the nail upon the highest and
    defined out the entire thing without having side-effects ,
    folks could take a signal. Will likely be again to get more.

    Thank you

  48. Hello, all the time i used to check web site posts
    here in the early hours in the morning, as i
    love to find out more and more.

Leave a Reply

Your email address will not be published.