Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Use the browser’s Page Visibility API to detect when a tab is hidden, and use window focus and blur only when your app needs to know whether its window is active. These are different signals: a window can lose focus while its page remains visible. In React, subscribe to the browser events in an effect, synchronize the initial state, and remove listeners during cleanup.
Visibility and focus are different signals
The Page Visibility API answers whether the document is visible to the user. Listen for visibilitychange on document, then read document.visibilityState or document.hidden. The event itself does not tell you the new state. A visible document generally has a visibilityState of "visible"; a hidden one has "hidden".
As an Amazon Associate I earn from qualifying purchases.
Window focus and blur events answer a separate question: whether the browser window is active. As MDN Web Docs explains in its Page Visibility API guide, “watching for blur and focus events on the window helps you know when your page is not the active page, but it does not tell you that your page is actually hidden to the user.” A user might switch to another window while your tab remains visible.
| Signal | Listen on | What it tells you | Typical use |
|---|---|---|---|
| Page visibility | document: visibilitychange |
Whether the document is visible or hidden | Pausing offscreen polling, animations, or other work that is unnecessary while the page is hidden |
| Window activity | window: focus and blur |
Whether the window is active | Behavior that specifically depends on active-window status |
Track both states with a React hook
This hook uses a safe initial value for server rendering, reads browser properties inside an effect, and cleans up all three event listeners. The browser APIs are not React events; React’s effect is where the component subscribes to them.
#1 Best Overall
import { useEffect, useState } from 'react';
export function usePageActivity() {
const [isVisible, setIsVisible] = useState(false);
const [hasWindowFocus, setHasWindowFocus] = useState(false);
useEffect(() => {
const syncVisibility = () => {
setIsVisible(document.visibilityState === 'visible');
};
const handleFocus = () => setHasWindowFocus(true);
const handleBlur = () => setHasWindowFocus(false);
syncVisibility();
setHasWindowFocus(document.hasFocus());
document.addEventListener('visibilitychange', syncVisibility);
window.addEventListener('focus', handleFocus);
window.addEventListener('blur', handleBlur);
return () => {
document.removeEventListener('visibilitychange', syncVisibility);
window.removeEventListener('focus', handleFocus);
window.removeEventListener('blur', handleBlur);
};
}, []);
return { isVisible, hasWindowFocus };
}
The initial false values avoid accessing document or window during render, which matters when a component is rendered on the server. The effect synchronizes them once it runs in the browser. If your app needs only visibility, omit the focus state and its two window listeners.
Pause only the work that should stop
Use visibility to gate work that has no value while the page is hidden. For example, a dashboard can stop polling while its tab is hidden and fetch fresh data when it becomes visible. Keep the policy specific to the task: a user may prefer a notification counter to keep updating even when an animation pauses.
const { isVisible } = usePageActivity();
useEffect(() => {
if (!isVisible) return;
const refresh = () => {
// Fetch or update data while the page is visible.
};
refresh();
const id = window.setInterval(refresh, 30_000);
return () => window.clearInterval(id);
}, [isVisible]);
Here, becoming hidden triggers the effect cleanup and clears the interval; becoming visible starts it again and refreshes immediately. Choose a refresh policy appropriate to your data, such as refreshing on return without polling continuously.
Recommended Free Tools
For visual work, visibility is usually the useful condition because it indicates whether the document is hidden. You may combine it with focus for a separate product reason—for instance, pausing an interaction when the window is inactive even if the page remains visible. Do not treat blur as proof that the page is hidden.
Rank #3
What hidden means—and what it does not
A hidden state can follow a tab switch, minimizing the browser, navigation, closing the page, or switching away from the browser on a mobile device. It does not prove that the user’s session has ended: the user may return to the page.
MDN describes the transition to hidden as the last reliably observable event in some page-lifecycle situations, making it a useful point for ending-session analytics. If you need to transmit analytics as a page exits, MDN’s example uses navigator.sendBeacon; do not rely on an unload handler as a substitute. See MDN’s visibilitychange event documentation.
Rank #4
Browser throttling is not app-level pausing
Browsers may throttle timers or stop requestAnimationFrame callbacks for background pages. That behavior is separate from your application’s own resource management. Explicitly stop unnecessary polling, subscriptions, or other work when your chosen state says it is no longer useful; do not assume browser throttling handles every task.
MDN’s Document.visibilityState reference reports that the feature has been available across browsers since July 2015; that is a compatibility milestone, not a performance measurement. The cited reference page was last modified May 8, 2024.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




