javascriptvue.jsbrowser

Custom pop up timer not working correctly


When socket messages come, I pop up divs in my page which disposes after 3 seconds themselves

<!-- I'm using vuejs -->

<div v-for='item in messageList'>
  <!-- message body ,  -->
</div>
// used to pause timer when mouseEnter and resume when mouseLeave
const mesTimerMap = new Map()

const messageList = ref([])
socket.on('message',function(mesBody){
  messageList.value.push(mesBody)
  let timer = setTimeout(()=>{
    handleRemove(mesBody) // in which I splice messageList
  },3000)
  mesTimerMap.set(mesBody.id,timer)
})

But I found that if I switch to other tabs and here comes a message, when I change back to my page, the pop up is still there even 3 seconds already passed. And I can not replicate this every time. Why is that?


Solution

  • Many browsers tend to limit background activities (timers, events etc.) when the tab is minimized for memory optimization, which all the scheduled events will trigger at once when user re-activates the tab. Consider using a service worker to handle the socket communication and message queue so it won't be throttled. Refer to this post and Service Worker API.

    If that would be an overhaul, you may also try adding a timestamp in the mesBody from your server side. Then if the message is expired when message event triggers, skip the popup logic.

    socket.on('message',function(mesBody){
      // if the message is already expired (10s buffer) when the event triggers, skip the process
      if (mesBody.timestamp < Date.now() - 10_000) return;
    
      messageList.value.push(mesBody)
      let timer = setTimeout(()=>{
        handleRemove(mesBody) // in which I splice messageList
      },3000)
      mesTimerMap.set(mesBody.id,timer)
    })