Table of Contents
Why should we care about auto logout?
Step 1: Implement tracking logic
Step 2: Tracking activation
Step 3: Improve performance
Bonus: Let’s reVue it!
That’s a wrap!
Home Web Front-end CSS Tutorial Detecting Inactive Users

Detecting Inactive Users

Apr 13, 2025 am 11:08 AM

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
}
Copy after login

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);
}
Copy after login

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
Copy after login

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);
  }
}
Copy after login

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);
  // ...
}
Copy after login

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
    };
  },
// ...
Copy after login

Then we move all our functions to methods:

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

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.

<template>
  <div>
    <p>User is inactive = {{ isInactive }}</p>
  </div>
</template>
Copy after login

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();
  },
// ...
Copy after login

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);
  }
// ...
Copy after login

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!

The above is the detailed content of Detecting Inactive Users. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Working With GraphQL Caching Working With GraphQL Caching Mar 19, 2025 am 09:36 AM

If you’ve recently started working with GraphQL, or reviewed its pros and cons, you’ve no doubt heard things like “GraphQL doesn’t support caching” or

Making Your First Custom Svelte Transition Making Your First Custom Svelte Transition Mar 15, 2025 am 11:08 AM

The Svelte transition API provides a way to animate components when they enter or leave the document, including custom Svelte transitions.

Building an Ethereum app using Redwood.js and Fauna Building an Ethereum app using Redwood.js and Fauna Mar 28, 2025 am 09:18 AM

With the recent climb of Bitcoin’s price over 20k $USD, and to it recently breaking 30k, I thought it’s worth taking a deep dive back into creating Ethereum

Show, Don't Tell Show, Don't Tell Mar 16, 2025 am 11:49 AM

How much time do you spend designing the content presentation for your websites? When you write a new blog post or create a new page, are you thinking about

How do you use CSS to create text effects, such as text shadows and gradients? How do you use CSS to create text effects, such as text shadows and gradients? Mar 14, 2025 am 11:10 AM

The article discusses using CSS for text effects like shadows and gradients, optimizing them for performance, and enhancing user experience. It also lists resources for beginners.(159 characters)

Creating Your Own Bragdoc With Eleventy Creating Your Own Bragdoc With Eleventy Mar 18, 2025 am 11:23 AM

No matter what stage you’re at as a developer, the tasks we complete—whether big or small—make a huge impact in our personal and professional growth.

What the Heck Are npm Commands? What the Heck Are npm Commands? Mar 15, 2025 am 11:36 AM

npm commands run various tasks for you, either as a one-off or a continuously running process for things like starting a server or compiling code.

A bit on ci/cd A bit on ci/cd Apr 02, 2025 pm 06:21 PM

I&#039;d say "website" fits better than "mobile app" but I like this framing from Max Lynch:

See all articles