<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alkesh Gupta</title>
    <description>The latest articles on Forem by Alkesh Gupta (@thealkeshgupta).</description>
    <link>https://forem.com/thealkeshgupta</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3593434%2F48e335ec-ab08-4c1d-86fc-54d11f1565b2.png</url>
      <title>Forem: Alkesh Gupta</title>
      <link>https://forem.com/thealkeshgupta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/thealkeshgupta"/>
    <language>en</language>
    <item>
      <title>Your Web App Keeps Running in Hidden Tabs — Here’s the Fix</title>
      <dc:creator>Alkesh Gupta</dc:creator>
      <pubDate>Sun, 02 Nov 2025 21:57:21 +0000</pubDate>
      <link>https://forem.com/thealkeshgupta/your-web-app-keeps-running-in-hidden-tabs-heres-the-fix-4k8h</link>
      <guid>https://forem.com/thealkeshgupta/your-web-app-keeps-running-in-hidden-tabs-heres-the-fix-4k8h</guid>
      <description>&lt;p&gt;Have you ever had music continue playing after switching tabs?&lt;br&gt;
Or dashboards keep polling APIs while you’re not even watching?&lt;/p&gt;

&lt;p&gt;Modern web apps often continue working unnecessarily when the tab is hidden — leading to wasted resources, wrong analytics, and a worse user experience.&lt;/p&gt;

&lt;p&gt;This article introduces a lightweight utility that solves that problem cleanly and consistently:&lt;br&gt;
&lt;code&gt;@alkeshgupta/tab-visibility&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's deep-dive into why tab visibility matters, how the browser behaves behind the scenes, and how you can leverage it in React or vanilla JavaScript immediately.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⭐ If you find this useful, consider leaving a star on GitHub!&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  🧠 The Hidden Problem You Don’t Notice (But Your Users Do)
&lt;/h3&gt;

&lt;p&gt;When a browser tab goes into the background:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Animations keep running&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Videos continue playing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Timers continue ticking&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API calls keep firing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Game loops keep looping&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leads to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;🔋 Battery drain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🐌 Performance degradation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📉 Incorrect business metrics&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📊 Wasted backend server resources&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;😡 Annoying UX (media keeps playing when tabbed away)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Developers often forget to pause/resume behavior based on tab visibility.&lt;/p&gt;


&lt;h2&gt;
  
  
  🔍 The Browser’s Behavior: A Quick Primer
&lt;/h2&gt;

&lt;p&gt;Browsers expose the Page Visibility API, which gives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;document.visibilityState&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;visibilitychange event&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The state can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;visible&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;hidden&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a user switches tabs, minimizes the browser, or switches focus — the event fires.&lt;/p&gt;

&lt;p&gt;Manually handling this looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;visibilitychange&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visibilityState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;pauseThings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;resumeThings&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But as you scale your application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need multiple listeners&lt;/li&gt;
&lt;li&gt;You need to clean them up&lt;/li&gt;
&lt;li&gt;You need to debounce/throttle events&lt;/li&gt;
&lt;li&gt;You need media control logic&lt;/li&gt;
&lt;li&gt;You need consistent behavior across browsers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It gets messy!&lt;/p&gt;




&lt;h2&gt;
  
  
  ❌ Traditional Implementation Pitfalls
&lt;/h2&gt;

&lt;p&gt;Most developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forget to remove listeners&lt;/li&gt;
&lt;li&gt;Duplicate logic across components&lt;/li&gt;
&lt;li&gt;Handle blur/focus inconsistently&lt;/li&gt;
&lt;li&gt;Mix UI and lifecycle logic incorrectly&lt;/li&gt;
&lt;li&gt;Don’t centralize presence handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even in React, it’s easy to introduce memory leaks.&lt;br&gt;
So we abstracted it.&lt;/p&gt;


&lt;h2&gt;
  
  
  ✅ What &lt;code&gt;@alkeshgupta/tab-visibility&lt;/code&gt; Solves
&lt;/h2&gt;

&lt;p&gt;This utility:&lt;br&gt;
✔️ Detects tab visibility changes&lt;br&gt;
✔️ Provides clean callbacks&lt;br&gt;
✔️ Supports multiple handlers&lt;br&gt;
✔️ Automatically pauses &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; &amp;amp; &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; elements&lt;br&gt;
✔️ Works in React AND plain JavaScript&lt;br&gt;
✔️ Requires zero configuration&lt;/p&gt;

&lt;p&gt;One API to rule them all.&lt;br&gt;
No boilerplate.&lt;/p&gt;


&lt;h2&gt;
  
  
  ✨ Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;onShow(callback)&lt;/li&gt;
&lt;li&gt;onHide(callback)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;autoPauseMedia()&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-callback support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Works globally&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simple and intuitive&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  📦 Installation
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @alkeshgupta/tab-visibility
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add @alkeshgupta/tab-visibility
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧠 Basic Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useTabVisibility&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@alkeshgupta/tab-visibility&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;useTabVisibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onShow&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tab is visible again!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;useTabVisibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onHide&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User switched tab!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚛️ React Usage Example
&lt;/h2&gt;

&lt;p&gt;Works anywhere inside your components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useTabVisibilityHook&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@alkeshgupta/tab-visibility&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useTabVisibilityHook&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;onHide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User switched tab!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;onShow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tab is visible again!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Watching&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt; &lt;span class="nx"&gt;visibility&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can register as many event handlers as you want.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔊 Auto Pause Media (Video/Audio)
&lt;/h2&gt;

&lt;p&gt;Automatically pause all &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;audio&amp;gt;&lt;/code&gt; elements when the tab becomes hidden:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;autoPauseMedia&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@alkeshgupta/tab-visibility&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;autoPauseMedia&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Optional - Ignore Muted Media:&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;autoPauseMedia&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@alkeshgupta/tab-visibility&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;autoPauseMedia&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ignoreMuted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧩 Vanilla Example (HTML)
&lt;/h2&gt;

&lt;p&gt;Works anywhere inside your components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useTabVisibility&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://cdn.jsdelivr.net/npm/@alkeshgupta/tab-visibility@1.0.1/src/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;useTabVisibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onShow&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tab is visible again!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;useTabVisibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onHide&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User switched tab!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧬 API Reference
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;onShow(callback: Function)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Registers a function to run when tab becomes visible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;onShow&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome back!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;onHide(callback: Function)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Registers a function to run when tab becomes hidden.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;onHide&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hey come back 👀&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;autoPauseMedia()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Pauses all video and audio elements on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;autoPauseMedia&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;autoPauseMedia({ ignoreMuted: true })&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Pauses all unmuted video and audio elements on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;autoPauseMedia&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ignoreMuted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧪 Testing Tip
&lt;/h2&gt;

&lt;p&gt;To test locally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open devtools&lt;/li&gt;
&lt;li&gt;Start logging visibility events&lt;/li&gt;
&lt;li&gt;Switch tabs&lt;/li&gt;
&lt;li&gt;Observe:

&lt;ul&gt;
&lt;li&gt;event triggers&lt;/li&gt;
&lt;li&gt;media pausing&lt;/li&gt;
&lt;li&gt;batched handlers&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;No special instrumentation required.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 When Should You Use This?
&lt;/h2&gt;

&lt;p&gt;Ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Media streaming apps&lt;/li&gt;
&lt;li&gt;Dashboards&lt;/li&gt;
&lt;li&gt;Trading charts&lt;/li&gt;
&lt;li&gt;Data visualizations&lt;/li&gt;
&lt;li&gt;Pomodoro timers&lt;/li&gt;
&lt;li&gt;Meeting &amp;amp; call apps&lt;/li&gt;
&lt;li&gt;Games&lt;/li&gt;
&lt;li&gt;Chat presence indicators&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Inside the Library (Technical Architecture)
&lt;/h2&gt;

&lt;p&gt;Internally, the utility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Registers a single visibilitychange listener&lt;/li&gt;
&lt;li&gt;Stores onShow/onHide callbacks in arrays&lt;/li&gt;
&lt;li&gt;Executes them sequentially&lt;/li&gt;
&lt;li&gt;Optionally inspects DOM media nodes&lt;/li&gt;
&lt;li&gt;Avoids duplicate attachment&lt;/li&gt;
&lt;li&gt;Works globally across modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This prevents event chaos.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛑 Common Pitfalls (Solved)
&lt;/h2&gt;

&lt;p&gt;Without this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You may pause media incorrectly&lt;/li&gt;
&lt;li&gt;Forget cleanup&lt;/li&gt;
&lt;li&gt;Attach listeners multiple times&lt;/li&gt;
&lt;li&gt;Cause memory leaks&lt;/li&gt;
&lt;li&gt;Miss subtle visibility states&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This utility removes risk.&lt;/p&gt;




&lt;h2&gt;
  
  
  📉 Browser Throttling Behavior
&lt;/h2&gt;

&lt;p&gt;Background tabs aggressively throttle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setInterval&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setTimeout&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;JavaScript execution priority&lt;/li&gt;
&lt;li&gt;&lt;code&gt;requestAnimationFrame&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So if you rely on timers — visibility is essential.&lt;/p&gt;




&lt;h2&gt;
  
  
  📜 Browser Support
&lt;/h2&gt;

&lt;p&gt;✅ Chrome\&lt;br&gt;
✅ Firefox\&lt;br&gt;
✅ Edge\&lt;br&gt;
✅ Safari\&lt;br&gt;
✅ Opera&lt;/p&gt;

&lt;p&gt;Uses the standard visibilitychange API, widely supported.&lt;/p&gt;




&lt;h2&gt;
  
  
  📏 Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;All callbacks can be registered multiple times.&lt;/li&gt;
&lt;li&gt;Order of callbacks is preserved.&lt;/li&gt;
&lt;li&gt;Works in frameworks (React, Next.js, etc.) after mount.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📎 Links
&lt;/h2&gt;

&lt;p&gt;GitHub Repo:&lt;br&gt;
&lt;a href="https://github.com/thealkeshgupta/tab-visibility" rel="noopener noreferrer"&gt;https://github.com/thealkeshgupta/tab-visibility&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;npm Package:&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/@alkeshgupta/tab-visibility" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@alkeshgupta/tab-visibility&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If this saved your time — please ⭐ on GitHub!&lt;/p&gt;




&lt;h2&gt;
  
  
  🤝 Contributing
&lt;/h2&gt;

&lt;p&gt;PRs are welcome!&lt;br&gt;
Add features, fix edge cases, or open an issue.&lt;/p&gt;




&lt;h2&gt;
  
  
  📜 License
&lt;/h2&gt;

&lt;p&gt;MIT — free for commercial &amp;amp; personal use.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Conclusion
&lt;/h2&gt;

&lt;p&gt;Handling tab visibility properly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Saves CPU&lt;/li&gt;
&lt;li&gt;Reduces power consumption&lt;/li&gt;
&lt;li&gt;Improves UX&lt;/li&gt;
&lt;li&gt;Optimizes analytics&lt;/li&gt;
&lt;li&gt;Keeps media behavior sane&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And instead of manually wiring event listeners + cleanup logic in every feature, you now have a reusable utility.&lt;/p&gt;

&lt;p&gt;Try &lt;code&gt;@alkeshgupta/tab-visibility&lt;/code&gt; in your next project 🚀&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>react</category>
      <category>opensource</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
