DEV Community

Cover image for The Optimization That Was Too Good: Why Our Push Notifications Only Worked When You Weren't Looking
Dhruv Jani
Dhruv Jani Subscriber

Posted on

The Optimization That Was Too Good: Why Our Push Notifications Only Worked When You Weren't Looking

Summer Bug Smash: Smash Stories πŸ›πŸ›Ή

This is a submission for DEV's Summer Bug Smash: Smash Stories powered by Sentry.

When I was building the push notification system for ShelfTalk β€” a real-time social app that won the GitHub Finish Up A Thon Challenge on DEV β€” I wanted to be considerate of my users. There's nothing more annoying than actively chatting in a web app and having your desktop ping you with a notification for the exact message you're currently reading.

GitHub logo JaniDhruv / ShelfTalk

A full-stack real-time social architecture featuring Socket.io instant messaging, synchronized reading rooms, and a high-performance React/Vite frontend backed by MongoDB Atlas and GridFS and desktop push notifications for groups and chats.

ShelfTalk Logo

ShelfTalk

Books don't talk. We do.

Turn every reading list into a living conversation.

🌐 Live Demo β€’ ⚑ Quick Setup β€’ ✨ Features β€’ πŸ›  Tech Stack

Node.js React MongoDB Socket.io Vercel


πŸ“– What is ShelfTalk?

ShelfTalk is a full-stack social community platform built for book lovers. Think of it as a blend of Goodreads and Discord β€” readers can share updates, annotate passages, join genre-based clubs, chat in real-time, and coordinate live reading sessions together.

Originally built as a college project, ShelfTalk has since been revived and significantly expanded with real-time infrastructure, a live reading room feature, a personal reading diary, an invite friends feature to help the community grow, cloud file storage, and more.


✨ Core Features

πŸ“ Community Posts

  • Publish reading updates and annotate favourite passages
  • Threaded comments keep every discussion organized
  • Reactions and saves from your personal dashboard

πŸ” Powerful Discovery

  • Filter readers by genre, location, and interests
  • Browse vibrant…

So, I added what I thought was a brilliant little optimization:

export const sendPushNotification = (title, options = {}, requireHidden = false) => {
  if (!('Notification' in window)) return;

  if (Notification.permission === 'granted') {
    // If requireHidden is true, only fire if the tab is hidden
    if (requireHidden && !document.hidden) {
      return; // <-- The "Brilliant" Optimization
    }

    try {
      const notification = new Notification(title, options);
      // ...
    } catch (e) {
      console.error(e);
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

The logic was simple: check document.hidden (the Page Visibility API). If the user is currently looking at the ShelfTalk tab, suppress the desktop notification. No redundant pings. Clean UX.

I deployed it, patted myself on the back, and went about my day.

πŸ” The Mystery

A few days later, the bug reports started rolling in. Users were complaining that they were missing important direct messages and group mentions.

I tested it on my machine. I minimized the browser, had a friend send me a message, and β€” ding! β€” the notification popped up perfectly. I opened the window, got another message, and no notification appeared. It was working exactly as designed.

So why were people missing messages?

πŸ’‘ The "Ah-Ha" Moment

I asked one of the users to describe their setup.

"Oh, I usually leave ShelfTalk open on my second monitor while I work on my main screen."

And suddenly it clicked.

The Page Visibility API (document.hidden) only returns true if the page is completely hidden β€” either behind other windows in a background tab, or in a minimized window. If the window is visible on a second monitor β€” even if you are actively working in a completely different app on your main monitor β€” document.hidden is false.

Because the tab was technically "visible" to the operating system, my code assumed the user was staring directly at it. It silently dropped every notification. The user, focused on their main screen, never heard a ping and missed the message entirely.

Even worse: if a user left ShelfTalk open on their desktop at the office and went home, their home laptop would never notify them either β€” because the office machine was technically still "looking" at the app.

TL;DR: document.hidden === false does not mean the user is paying attention. It just means the OS can see the window.

πŸ”¨ The Smash

Sometimes, the best way to fix a bug is to delete the code you were so proud of writing.

I removed the optimization entirely:

-    // If requireHidden is true, only fire if the tab is hidden
-    if (requireHidden && !document.hidden) {
-      return;
-    }
+    // Notifications will now fire even if the tab is visible,
+    // to ensure they appear across all active machines.
Enter fullscreen mode Exit fullscreen mode

(See the exact commit here)

πŸ“– The Lesson

We often try to be "too smart" with our UX optimizations. I assumed that "window visible" equaled "user paying attention." In the era of ultra-wide monitors, multiple screens, and users being logged in on five different devices at once, that assumption was completely wrong.

By trying to save users from a slightly annoying notification, I ended up breaking the core promise of a notification system: telling you when something happens.

Three things this bug taught me:

  1. Test with real user setups, not just yours. My single-monitor dev machine couldn't reproduce the issue. Multi-monitor setups, tablets propped up on desks, browsers left open on work machines β€” these are all "visible" to the OS.

  2. document.hidden is about the OS viewport, not human attention. The MDN docs are clear about this, but it's easy to project human meaning onto a boolean that was never designed to carry it.

  3. When in doubt, notify. A slightly redundant ping is annoying. A silently dropped message is a broken product.

Now, ShelfTalk might ping you even if you're looking right at it. But at least you'll never miss a message again. πŸ””

Top comments (2)

Collapse
 
dj29 profile image
Dhruv Jani

One of those bugs that makes you rethink what β€œvisible” actually means.

I thought I had a clever notification optimization. Turns out document.hidden and β€œthe user is actually paying attention” are two very different things.

Hope this one saves someone else from making the same mistake. πŸ””

Collapse
 
anasbuilds997 profile image
anassBld

Great debugging story. Your "Ah-Ha" moment is actually a specific instance of a general distributed-systems trap: inferring client state from a single signal.

document.hidden told you about the OS viewport, but you used it to model human attention β€” and attention was never the thing being measured.

The fix that usually survives multi-monitor reality without fully reverting is to combine signals: fire the notification, but let the client acknowledge receipt (focus event, service-worker interaction) mark it as seen. That way you optimize for "don't annoy an attentive user" based on observed behavior rather than predicted attention β€” closer to how push systems treat delivery vs. read receipts.

The deeper lesson matches what we keep hitting building agent infrastructure: any state inferred from one observation ("visible", "returned 200") should stay provisional until confirmed by a second independent signal. Congratulations on the Finish-Up-A-Thon win, by the way.