Indie Hackers should be much faster nowadays… at least for some of you!
In the past week, the PageSpeed Insights score for our homepage on mobile jumped from 24 to 78. On desktop it jumped from 40 to 97. Not too shabby!
We had similar improvements on post pages, which are just as important (if not more): from 22 to 79 on mobile, and from 57 to 98 on desktop.
The vast majority of the speedup came from two improvements: (1) serving static pages, and (2) optimizing images.
Indie Hackers is a single-page application (SPA) with server-side rendering. When you visit the site, you have to wait a few seconds for the JS to build the single page app in your browser. For some routes we have server-side rendering, so at least you'll see the full page of HTML while the SPA boots up. On others, you just see a random quote to distract you from how slow it is. 😈
However, It turns out that static HTML is all we really need for anonymous visitors. They don't actually need the SPA to boot up. So I wrote some code that lives on the edge nodes of our CDN. It modifies the HTML response to simply strip out our SPA JS. It also strips out lots of JS and CSS that were only used for the SPA, and replaces them with smaller page-specific JS and CSS.
The result is that, for anonymous visitors, the homepage and post pages load almost instantaneously when they're cached in our CDN. They take a second to load when you get a cache miss, but I've set the cache to last for 7 days, so it should be rare for popular posts. I've also got some good cache invalidation going on, where I'll refresh a post page in the cache when it gets new comments, edited, upvoted, etc. This kind of stuff is a pain to code and maintain, but it's necessary for a dynamic site with lots of visitors to pages that change frequently.
Anyway, this was the vast majority of the speed improvement. In the future I'd like to do the same for logged-in users, but that's a bit trickier, since there's a ton of JS in the SPA that deals with logging you in and allowing you to interact with various components (e.g. leaving comments and upvoting things).
"But Courtland, why did you make IH a SPA to begin with?"
Because it was a fun hobby project when I started it, and I didn't know it would get big leave me alone okay jeez.
This was a relatively simple fix, but it took a while. When you upload an avatar to your IH profile, I've got some code it automatically resizes it down to 72x72 pixels. However, I never got around to wring similar code for product and group icons. And if you look at the homepage, it's absolutely littered with lots of these icons, which makes it bright and happy, but also super huge. If you're on a slow mobile connection, the last thing you want is to download 3MB of images every time you visit the site.
So I spent some time optimizing all of these images. First, instead of merely shrinking them to one size, I'm shrinking them to 3 different sizes, and using the smallest possible size wherever I can get away with it. For example, group icons have a 28x28 pixel size for use in the social feeds around the site:
Second, I'm also converting these images to WEBP, which is a better compression algorithm than both JPG and PNG. The homepage still has way too many images, but now they're just a few kilobytes each on average, whereas before they were often dozens or hundreds of kb each.
Besides the above, there were a lot of smaller things, too. And my list of potential speed improvements is still super long. But I'm happy enough with the progress so far to move on to other things for a little bit.