Day 22: How Hide Feed hides feeds
I haven’t been able to work much these past few days (and won’t be able to for the next few days) due to moving out of my place in Austin, so I’m going to use today’s post to basically add some documentation. This is not going to make interesting reading unless you’re somehow really interested in the subtle details of how Hide Feed works so if I were you, I’d stop reading here and come back another day.
I strive to write software that does the right thing 99% of the time without the user having to think about it. Everything should just work, and if I’m doing it well, the user shouldn’t even notice that I’ve made a ton of decisions for them. As you’ll see below, answering seemingly simple questions like “when should the feed be hidden?” can require nontrivial work to get right.
Let’s think of the simplest implementation of an extension like Hide Feed that hides elements on websites. Whenever the user loads a site that matches a particular domain, apply some CSS that hides elements on a page. But what if you want to let the user toggle that CSS so that they can sometimes view the hidden elements? You add some Javascript to undo the CSS changes. Easy.
Now here comes the tricky part: What should happen if the user leaves the page and comes back? Or if they refresh the page?
Option 1: Always hide on load
The first option is to keep everything stateless. If they refresh the page, then everything is hidden again and they need to choose to show the feed again. While this is appealing due to its simplicity, it can lead to some pretty annoying user experiences.
Consider Gmail where the inbox is hidden so that users can search and reply to messages without being distracted by new emails. Say, for example, that a user goes to gmail.com, shows the inbox, and then clicks an email to read it. When they finish reading the email, they go back to the inbox.
With this first option, the inbox would be hidden again. That would get tiresome super quickly as the user would need to unhide the inbox every time they navigate back from reading an email.
Option 2: Keep the same state
What if we persisted whether the inbox is hidden or not? If they show the inbox, it would stay visible even if they left and came back, which means that we wouldn’t have the annoying problem above. But now we have a new problem: The user has to remember to hide the inbox before leaving. Otherwise, if they show the inbox and close the tab, the inbox will be visible the next time they come back. That would defeat the whole purpose of the extension because they might already have been distracted by some new email. It shifts the burden onto them to remember to clean up after themselves.
Option 3: Smart sessions
So it looks like we need to somehow manage the hide state so that (1) the inbox stays visible in the same session but (2) the inbox is hidden again when they user leaves and come back. But how do we know when they’re in the same session and when they’re starting a new one? This is where we have to start using our product sense to make reasonable assumptions.
A clear case where we can safely assume that a session is over is when there are no more tabs with Gmail open, either because the user closed the tab or they navigated to another site. When that happens, we can hide the inbox for the next time the site is loaded.
But are there other instances where we might want to automatically hide the inbox? What if the user puts their computer to sleep and opens it an hour later? In that scenario, they’ve probably had enough of a context switch where it makes sense to hide distractions (e.g. the inbox) again.
To handle those cases, we can automatically end the session when the user has been idle for more than a certain amount of time. And we can apply this to not just the user being idle from the whole computer, but for them being idle from that site. In other words, if they switch away from Gmail for more than the idle threshold, the inbox would automatically become hidden again.
So to summarize, here are the conditions under which the feed/inbox is hidden automatically for a site (e.g. Gmail):
- All Gmail tabs are closed or change URLs
- All Gmail tabs are inactive for more than the idle threshold
- The computer is idle for more than the idle threshold
And this is just the start. From here, we’d need to figure out the implementation details like how we’d detect that the user is idle, how long the idle threshold should be, and whether a feed’s visibility should be synced across tabs or only affect the current tab. Even a relatively simple product like Hide Feed requires a lot of care in order for everything to just work.
And sometimes, you think you’ve figured everything out only to realize that your assumptions completely break down in certain cases. For example, consider YouTube. If a user shows the YouTube sidebar recommendations on the watch page and clicks on a video, should the sidebar recommendations be displayed again for the next video? While that would keep the design consistent with how hiding the feed works on other sites, consistency might not be warranted here: keeping the inbox visible between emails is not the same as exposing the user to sidebar recommendations for every video they watch. On most sites, when the user shows the feed, the intention is to browse the feed, so it’d make sense to keep it visible; for YouTube’s sidebar recommendations, the intention is to watch another video, meaning that the feed itself isn’t the point of interest. For that particular case, it seems more appropriate to add the additional friction and always hide on load (option 1).
One way to deal with these nuances is to provide settings for the user to configure everything themselves. Then they can choose the exact behavior that they want for every type of feed. But a great user experience doesn’t mean providing an endless number of settings so that users can tweak every little thing to get things just right — it means doing the hard work so that they’ll never have to.