Complete: Classic Interfaces
This month I designed, built, and deployed classicinterfaces.com.
I had much less time to work this month than last, so the goal was to build something that would take <10 hours of effort. All in all, this website took about 18 hours, which is a nice reduction from phraseranker's 35 hours. Once again, I probably could have built it in 10, but I made two primary choices that made that difficult.
Source of complexity #1- image loading. Since this website is mostly images, I thought it would be a good idea to spend some time creating a nice image loading system. I implemented a blur-in loading component, which was pretty nice, but required quite a bit of work up front. It meant pre-rendering images at smaller sizes, which meant learning a new image manipulation library and integrating it into the markdown parser (a plugin for rollup) I was using. This was fine, but took a while to figure out, especially as the library uses a lot of promises and evidently you can't do anything asynchronously in a rollup plugin. Then there was time spent messing around with css filters and styling to get the formatting right, which I had to return to again when I realized my system didn't work as nicely as I wanted for vertical images. I then had to add more to the markdown plugin, fetch some meta files, conditionally add some css classes, etc etc. It was more time than I should have spent on something that was really just a small detail.
Source of complexity #2- filtering. I wanted a nice filtering system for this website; it kind of relied on being able to find certain kinds of interfaces through filtering. I planned ahead of time for this to take more of my time than any other part of the site, but didn't realize the extent of it. Building the site without a database meant that I was just working with a list of json objects, which meant I had to implement my own filtering method from scratch. I wanted it to be performant enough, but didn't want to overwork making it as efficient as possible. I think generally I succeeded in this endeavor. The filtering works without employing too many fancy algorithmic tricks. When the server starts up, it creates lookup tables for each of the attributes that can be filtered (date, operating system…) containing each attribute option and arrays of slugs (basically the id of each interface). When a filter is received, it gets the arrays at each attribute value and finds all overlapping slugs within them. This solution seems pretty fast but is of course limited in all these lookup tables remain in memory and with many objects would get quite large. I don't foresee having that many interfaces though, and if I did would probably rewrite the backend to use a database anyway.
The main takeaway here is that I added on complexity somewhat unnecessarily through the use of fancy image loading and misjudged the amount of effort filtering would take to get right. As I continue to make these websites I think I'll develop a better sense for the amount of effort certain tasks will take and adjust my plans accordingly. I'll also have to be better about not following the temptations of little details like sexy image loading and stay focused on the main functionality—this happened in the previous website as well.
Did I learn something about simplicity this month? Definitely: focus on the important parts. Keep everything else as simple as possible. The filtering system is the core piece of complexity for this website, and everything else should be as minimal as possible. I knew this going in, but still managed to find ways to make things more complicated.
Some stats:
--------------------------------------------------------------------
Language files comment code
--------------------------------------------------------------------
Svelte 8 7 695
JavaScript 9 60 456
Markdown 37 0 376
JSON 4 0 57
CSS 1 0 38
HTML 1 10 19
YAML 1 0 9
--------------------------------------------------------------------
SUM: 61 77 1650
--------------------------------------------------------------------
About 100 lines of code less than last month. It's a bit misleading though because a good chunk of that is markdown, which took much less effort to generate. The Svelte/JS categories are more relevant. As a comparison, last month I wrote 1150 lines of Svelte as compared to this month's 695 lines. So a nice reduction there. The overall goal of this project is not less code per se, but it's somewhat representative of the simplicity of the site from the implementation perspective. Fewer pages, features, and details = less code.