Portfolio
This is my stuckinsnow.com project.
- Go
- TypeScript
- Preact
Stuckinsnow
When I planned building this site, I intentionally ignored most of the common advice: keep it simple, don’t over-engineer, and ship quickly. For me, over-engineering is a way to learn and setting imaginary constraints forces you to solve problems you wouldn’t normally encounter in personal projects (and the edge cases that follow).
Tech Stack
The site is built using Go, vanilla JavaScript, PostgreSQL, DragonflyDB (redis) and AWS S3 for storage. I'm also using Preact, which I will get into a bit later.
Benchmarked with WRK, the home page can handle 550,000+ requests a second i.e. about 100x faster than NextJS. In practice, this comparison is mostly theatrical--NextJS scales extremely well horizontally and with a CDN in front of it, you won't notice a difference.
That said, I wanted to explore supporting a large number of concurrent users without relying on a CDN. So I began looking at popular websites e.g. LinkedIn, Stackoverflow, etc. and reading how they overcame performance problems.
Big Tech
There's lots of little tricks in how FAANG increase performance. For example load stackoverflow, view the network request panel and click the comment editor. You'll notice that it's fake html until clicked. These kind of tricks are everywhere and very simple, but you may have missed them. They add up over time, but they can also mess up your codebase, so I realised I needed a methodical system.
My solution here was to build an app to help with building assets. I prefixed CSS and JavaSript that should be above the fold or inlined, with inline-;this then gets automatically injected. Part of me wonders if it should only do this on page landing i.e. if you're navigating from home, it should perhaps prefetch CSS instead and not inline anything.
On the topic of CSS, using SCSS over Tailwind was a conscious decision. I wanted to separate myself from those too reliant on AI (AI is very good at Tailwind). But it was later for performance reasons; while it's true that Tailwind is probably faster than SCSS in general, if you inline correctly SCSS is technically faster--Tailwind bundles all classes used on your site, even if you don't use them on the page. I'm prepared to accept I'm wrong on this, but I tested and in practice, I wasn't able to get 11ms page loads with Tailwind.
If I were to remake the site, I would use regular CSS; its nesting uses less bytes than SCSS and is superior in my opinion.
Data
Compression is handled in a slightly more complicated way than NextJS. With NextJS, an invalidated page typically returns uncompressed HTML. With this, I minify and inject JavaScript and CSS into Gohtml files -> compress into Brotli and Zstd; the binary is stored in redis, and then there's a short term memory cache. If everything is invalidated, it will still serve a compressed page. WRK proved to be particularly useful as I could challenge myself e.g. what if 1,000 people view the page at the same time? Here is where I learned you can compress and stream zstd on the fly, while you're compressing brotli in the background and serve uncompressed HTML if you're flooded. Honestly, a complete waste of time--and a headache--but headaches are a good place to learn.
With images, the dimensions are stored in the database, plus a base64 string that gets inlined into the HTML, and then it loads the actual higher resolution image later. The result here, I think, is a pleasing blur with no layout shift.
HTML
You may notice if you inspect the page, the HTML looks very strange. The actual structure of the project is well organized, and I've grown to not completely hate developing with vanilla javascript. That said, this has given me an appreciation for all of what NextJS does automatically for you. It's also been a good way to learn what it doesn't do.
For the richtext editor, I decided to use Lexical. I've been a huge fan of it ever since using Payload CMS, and you can customize it a lot. Its output is a tree, and is very easy to render with Go.
1 "dependencies": {2 "@lexical/code": "^0.35.0",3 "@lexical/link": "^0.35.0",4 "@lexical/list": "^0.35.0",5 "@lexical/react": "^0.35.0",6 "@lexical/rich-text": "^0.35.0",7 "@lexical/selection": "^0.35.0",8 "@lexical/table": "^0.35.0",9 "lexical": "^0.35.0",10 "preact": "^10.19.0",11 "preact-router": "^4.1.2"12 },
Here I'm cheating, because I'm exporting a Preact bundle that's then attached to a div. Generally I try to avoid libraries (and no, the syntax highlighter above is not a library) but Lexical is too good to ignore! This is then lazy loaded on a separate endpoint, along with the comments. These are also stored in redis. The advantage with this is many people can hit the like button at the same time and the page serves compressed HTML as normal, while showing updated content across servers (at the time of writing, I'm only hosting on one).
Design
I can add templates by creating new Gohtml pages, and these get added to the theme system. Then any pages I create can use these pages. Purple is one of my favourite colours, so naturally there had to be a lot of purple!
Published: Dec 16, 2025