Hi, I’m a fan of Discourse, from a small community that is talking about migrating from vBulletin5. One person was opposed to Discourse because “Hijacking Ctrl+f is evil” and after seeing what they meant, I have to agree. There is a serious usability issue with how Discourse currently handles Ctrl+f, which is the browser’s shortcut for “Find text within this page”.
- Some of the time, Ctrl+f works as it should and Discourse uses the browser’s builtin find function so that the page scrolls to the first hit immediately as you type. Ctrl+G takes you to the next hit.
- Life is good.
- Some of the time Ctrl+f doesn’t work and instead shows a list of results from a database search.
- It does not scroll the page to the first hit as the user types.
- The search phrase is only highlighted if it happens to be on the screen already.
- It does not allow searching for terms that are too short, such as “UX”.
- It does not accept Ctrl+g to show the next hit.
- It does show results for irrelevant topics that Ctrl+f would not have shown if it couldn’t find the term on the page.
- Why this breaks is completely invisible to the users, but it is extremely frustrating. They feel the ability to search within a page has been taken away with no explanation.
- It does not help to tell them that hitting Ctrl+f twice will do a browser search as that would fail to find posts that actually exist.
This is not a cosmetic issue, but a fundamental usability problem that Discourse will need to fix at the root: the illusion that an entire conversation is actually in the browser’s DOM, when instead it is loaded dynamically.
When there are more than twenty posts in a topic, Discourse sends posts to the browser only as needed. You could view a thread of over a 1000 posts with almost no load on the server because most of the DOM is just empty stubs. That’s a brilliant idea, but it’s also what causes Ctrl+f to mysteriously break.
I’m not suggesting getting rid of the illusion, as I think it is worthwhile. Discourse was right to jettison the old way of splitting up conversations into arbitrary pages with 40 or so posts each.
Discourse just needs to do better at making the illusion seamless.
To be honest, I don’t know the best solution to this, but I have some thoughts that I hope will be helpful.
First, here are some simple ideas that are reasonable if Discourse is going to break the illusion by switching to a database search,
- Let the user know what’s going on. Put a little note where the browser’s find box would normally appear with an apology and explanation.
- “We’re sorry, but this topic has 1002 posts in it, but your browser only has 7 of them loaded so Find in Page probably won’t work. If you want to try anyway, hit Ctrl+f again.”
- Let the user have some control. When a user hits Ctrl+f, show a button so that users can manually load the text from all of topic’s posts into the DOM.
- If that is deemed impossible due to the limit of 100 posts cached in the browser at one time, then show a button that will let user’s fall back to the old way of viewing topics: broken up by page.
- “Click here to view this topic in a way which works with Ctrl+f: [Page 1]         […] [>>]”
- Increase the default cutoff from 20 posts to 100 posts. This might not be too difficult to change as Discourse is already able to cache that many posts in the DOM.
Of course, those ideas are ugly and I think of them as only stop gaps. Eventually, the best solution would be for Discourse to implement Ctrl+f in a way that works the way people expect. Replicating in Discourse what the browser does for interactively searching would be very much worth it, but I imagine it would be difficult.
However, but there might be a (relatively) simple solution.
I believe the best solution for Discourse is to only remove media objects from the posts, not text. Then, there would be no need to “hijack ctrl+f” and replace it with a database search.
Find in Page only searches for text, so there is no need for the browser to have the entire DOM loaded to be able to search it. Text is incredibly lightweight to send, especially if the HTTP server has gzip compression turned on. Text also does not take up much memory in a web browser.
You all will know this better than me, but I have some guesses:
- Average post size: 5 KiB of text
- Average topic length: 50 replies.
- Average text to transfer: 250 KiB which seems reasonable.
Of course, every byte matters for responsiveness. If my estimates are off and the size of the text is an issue, filling in the DOM with text could be done as a background process after the important parts of the page have been sent. If the DOM hasn’t been completely populated with text at the point when the user hits Ctrl+f, a meter can appear, letting the user know to wait and showing the progress as the text trickles in.
While it is a serious problem that ctrl+f breaks the illusion Discourse creates, I’m impressed with the amazing work the Discourse devs did in creating that illusion in the first place. I am confident they will eventually find the right fix for this, too.
Thank you for taking the time to consider my suggestions.