Edit: Thank you so much for taking a look at Seen! Yes, I know, it's really slow. And scrolling does not render notes instantly. And the title is a bit clickbait-y. I'll try my best to improve on it though. This is just a preview, the most basic version of Seen, and it's getting there. But, oh God, I almost got a heart attack when I opened up Vercel Analytics and saw ~1,500 page views, up from 10 or 12. Thank you again! It's such a weird experience showing something to the world for the first time as a 16-year-old and seeing so many people look at it.
Hello HN!
I've been working on creating a new note-taking app called Seen. Right now, it's really just a preview: virtual-list rendering ~1,000,000 notes in a masonry layout, while trying to minimize CPU and memory usage as much as possible.
Seen currently has:
- A client-side search feature
- Creating, updating, deleting the topmost note (locally; no changes are saved to any server)
- Automatic repacking of the masonry layout when the window width changes
- A lot of bugs, I'm sure
I reached a point where I thought I was ready to show the Seen to the world, and this is it. It's pretty basic, I know, but I'm really proud of it.
Seen was born out of an experiment to see just how fast things can become if you use the right techniques, and will (hopefully) achieve this dream sometime in the near future. My vision for Seen is to create something that can handle a lot of notes while using the least amount of resources. If you've got any suggestions or bugs, they're welcome in the comments!
A little about how Seen works: during the first visit, Seen caches note heights for the specific window width. Seen also caches the HTML output for the Markdown notes. It caches height by the key SHA256(title + note content), and the Markdown-to-HTML renders by the key SHA256(note content). It uses this cache every other time instead of recalculating, meaning that if most of the content remains unchanged, Seen can render things pretty fast. Caches are saved to IndexedDB.
When window width changes, the amount of text that can fit in a line also changes. So, Seen caches heights for specific window widths as well, putting the width in the key. Scrolling triggers an event handler that calculates the current viewport and finds & renders all notes that are visible (or partially visible) with a buffer of a 600px.
When a note is deleted or inserted, the entire layout is re-rendered. I plan on optimizing this to only re-render the specific column, which is what happens anyway when a note is updated. Updated notes create new caches (as they should).
- Too much on band calculation blocking the renderer when the new items come into view.
- Not enough preloading of the items off screen
- Incorrectly calculating the virtual scroll height which causes inefficient re drawing during render.
Not sure what stack you’re running but it seems the table could use some optimization.