2014-12-02

Sweating the Small Stuff

Thoughts about the importance of diving deep into technical details.

Recently I've been sweating the small technical details of this website (and the web in general).

First detail: should this site's urls have www or not? Should it be www.highwaterlabs.com or highwaterlabs.com.

to www or not to www

Right now the www just redirects to the naked domain with no www. When I made this decision, I had a vague sense this was the wrong way to do it, but I didn't really understand why. So when my DNS and redirects and Github didn't play well together, I just said "fuck it" and dropped the www. But now I know: omitting the www makes it impossible to set cookies that are sent with requests to www.highwaterlabs.com but are not sent with requests to other subdomains, like images.highwaterlabs.com.

More about why here:

I hand't spent a lot of time playing with cookies until about a month ago. Cookies, along with the other HTTP headers, are such an important part of the internet. They are a part of every request: every webpage you visit, every image you download, every form you fill out.

"So what?" is the standard answer to such miniscule concerns, "So what if we send a couple extra cookies? We'll work around it if and only if it becomes a problem. The extra headers do hurt performance a tiny amount, but it's imperceptible on desktop and (probably) imperceptible on mobile. For extremely large sites, the extra headers might require an extra server or two on the backend. But other than that, the extra headers won't matter much."

But it does matter. For one, once you know the right way to do it, it's no harder to use www instead of the root domain for all your future sites.

If your cookies and other headers are a black box that your framework just handles, you can get pretty far with just that. But sooner or later, you will run into behavior you can't explain or understand without understanding your headers. Bugs involving HTTP headers will come up in any reasonably complex web application. When that happens, having fewer headers to sort through will save developer time and effort.

It will also probably prevent some bugs from arising with the headers in the first place. Bugs and complexity go together like peanut butter and jelly.

But headers are way more than just a source of bugs. They are also a powerful tool you can use for your own advantage.

And so on. There are lots of HTTP headers.

simple is beautiful

I've been obsessing over performance more than many web developers would consider healthy.

Firstly, I started only including the necessary CSS for each specific page, rather than loading all the damn CSS for the whole website in the base template. Not only does this improve performance, it also makes the CSS way more intelligible. The syntax highlighting css is only included in pages in the blog section of the site, where it might actually be needed.

I've also simplified the DOM as much as I possibly can. I am firmly of the belief that a slim DOM is a happy DOM. A deep DOM tree leads to confusion and awkward CSS hacks.

A great way to keep your DOM and CSS as simple and small as possible is to pretend you have an ancient computer and dialup internet. And that every new CSS rule and DOM element will hurt performance.

Of course, you and your users aren't on devices or networks that slow. And a lot of developers would point to this and say such micro-optimization is a waste of time.

But this CSS and DOM discipline leads you to become a better developer. You will think in terms of efficient, modular CSS files and good DOM structures. It leads to a site that is much easier to understand and reason about as a developer. In the vast majority of cases, a simpler, more maintainable site more than pays for itself over the long term.

It's also just more fun to hack on. Good code is fun to hack on. Bad code is annoying to hack on.

tearing off the bootstraps

To simplify the site even more, I removed jQuery and Bootstrap.

jQuery is king. And I like jQuery a lot. But vanilla Javascript is rapidly reaching the point where it's just as readable. You might not need jQuery anymore.

Vanilla Javascript will always work. But in the future, a lot of projects will cease to include jQuery. Like Angular 2.0.

I also removed Bootstrap. Bootstrap feels huge and clunky and bloated to me these days. As I learn more and more CSS, Bootstrap becomes more and more frustrating. Why oh why would I use the oh so laborious Bootstrap grid system when a few simple media queries would do the job quicker and better?

Not to mention, Bootstrap hopelessly entangles form and content with its classes. You don't just have the nav and then style it arbitrarily differently based on @media state. Instead, you stack on a thousand different classes and counter-classes and have to keep each straight in your head. And in the end you still have to add a few media queries to actually make it all work right.

Why do I want to memorize the billion and one Bootstrap classes and DOM structures when I could just learn and use the damn CSS rules myself?

Normalize CSS and a tiny subset of the Bootstrap CSS provide all the functionality I need. Specifically, just these ~30 lines of Bootstrap copypasta.

Due to removing jQuery and Bootstrap, a load of my about page now uses this data:

GET /about/ 2.6 KB
GET /t/css/normalize.min.css 2.1 KB
GET /t/css/a.css 1.5 KB

Before, in addition to the above requests, all this loaded:

GET /jquery/jquery.min.js 83K
GET /bootstrap/css/bootstrap.min.css 111K
GET /bootstrap/js/boostrap.min.js 35K
GET /bootstrap/fonts/* 146K

(Note: google_analytics.js``` 16.1 KB also loads but it is a script tag at the end of the page and won't affect load or render time.)

Look at the size of those beasts! That's an enormous amount of data for a simple blog.

Small websites are more mobile friendly. Obviously, small sites load faster on a slow and unreliable mobile connection. But using less data has another benefit. Consider the user who gets only 500 MB of data per month from their mobile provider. A single visit to my simple blog was uses up:

Before: 397.3 KB
After: 22.3 KB

Before, 0.8% of the user's mobile data for the month was used just by visiting my site once.

After, it takes 18 visits to my site to use the same data as a single visit used to.

Subsequent visits are not much better. I use Github Pages as my host, and it has a fairly low max-age. The header is Cache-Control: max-age=600 which means that all the static files are refetched every 600 seconds. Which in turn means that if a user goes to a page on your site, goes and does something else for 10 minutes (which happens all the time because internet), then goes to a second page on your site, ALL those files will be fetched again.

So 12 visits. Each separated by an hour or more. That all it took before for a mobile user to use 1% of their data just to visit this very simple, mostly text website.

conclusion

For years I've been fascinated by the web. What is this simple system that enables me to see the creations of billions of others, to read and listen and watch and buy and think? All for free, instantly, just by typing in a couple search terms or a url.

Even after years of learning about the web and building things on it, after years of blogging and full-time web development, I feel the same. The internet is a magical place.

Why do developers take this simple, elegant system and make it so unnecessarily complex and unwieldy? Keep it simple stupid.