Personal website case study
Tags: gatsby, webgl, showdev, blogging
Published: 2020-10-15 10:51:43

---
title: Personal website case study
published: true
date: 2020-09-30 09:00:00 UTC
tags: gatsby, webgl, showdev, blogging
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/y56cpxtkm3z5me9fekov.png
canonical_url: https://alvin.codes/writing/under-the-hood-tech-stack
---

I recently launched my personal website. It took a while and was a slog at times, but I learnt a lot along the way. It feels very "me" now.

The launch day went beyond my expectations. I got lucky that  Josh Comeau liked it enough to [tweet](https://twitter.com/JoshWComeau/status/1313124798948663298) about it. The numbers were nice, but the most important aspect was the response: People were impressed and genuinely liked it.

Hopefully folks here will be interested in what's going on under the hood.

- [Requirements](#requirements)
- [WebGL](#webgl)
- [Gatsby wish list](#gatsby-wish-list)

Disclaimer: For brevity’s sake I’m assuming a fair bit of prior knowledge. If you would like to learn more about something mentioned here, let me know [on Twitter](https://twitter.com/alvinometric) or here directly.

## Requirements

- Minimal tech lock-in
- High lighthouse score (95, at least)
- Try to reduce bundle size as much as possible
- The reading experience works without JavaScript

### Minimal tech lock-in

I don’t want my site to rely on a specific technology too much. I don’t use CSS-in-JS, I hardly use React hooks or component methods, and favour implicit declarations over “Gatsby magic.” Everything should be easy to reproduce with another generator.

I feel like I made the right choice with Gatsby, and it boils down to two time-saving elements: _plugins_ and _built-ins_.

Do you want a dark mode? Here’s `gatsby-plugin-dark-mode`. Crazy WebGL graphics with [glslify](https://github.com/glslify/glslify)? You’ve got `gatsby-plugin-glslify`. An RSS feed? Yep. Gatsby even optimises my images, and adds `aria-current` to active links.

On the Markdown side of the house, I dearly missed Jekyll’s fantastic defaults, but again: Plugins! [Remark](https://remark.js.org/) (the markdown processor) has itself a thriving ecosystem. I got footnotes, custom expanding blocks and table of contents by adding the corresponding plugins.
You can see examples on the original post.

I’m also pleased that I didn’t have to fiddle with Gatsby internals too much.

### High Lighthouse score

![Screen shot showing a hight lighthouse score](https://dev-to-uploads.s3.amazonaws.com/i/0jyl8loun0g7njh9o1kf.jpeg)

This is for the homepage that has a WebGL sketch using post-processing.

### Reduce Bundle size

Throughout the development process of this site I was ruthless when it comes to dependency sizes:

- I run every dependency through [package-size](https://www.npmjs.com/package/package-size) to make sure there isn’t a smaller alternative, and including it is weighed against its cost.
- The fonts are compressed as Woff2 files and self-hosted.
- Preact is used to make the Gatsby runtime 30% smaller.

WebGL sites tend to have needlessly large bundle sizes, here’s my answer to that.

## WebGL

This site was another excuse to experiment with 3D graphics, shaders and WebGL. Three.js was ruled out from the start because of the ~~ridiculously~~ large JavaScript size. I tried to strip most features out of Babylon.Js but the bundle was still too big. I ended up using [Regl 👑](http://regl.party) which is way more lightweight but more low-level, (you have to write GLSL). It’s [battle-tested](https://www.theguardian.com/us-news/ng-interactive/2016/nov/08/us-election-2016-results-live-clinton-trump), has been stable for years, and isn’t changing any time soon. Fun fact: Mikola, the creator of Regl, even moved off-the-grid to a lava field at one point and no problem happened with the library.


I’m keeping an eye on [OGL](https://github.com/oframe/ogl) which is an even smaller WebGL library and even gives us a scene graph out-of-the-box, but the API isn’t final yet.

Here’s how they compare (minified size):

- 632.33 KB – Three.js v0.120.1
- 110.85 KB – Regl v1.6.1
- 98.39 KB – OGL v0.0.60

Picking Regl over Three.js saves us 500kb, more than a _five-fold_ decrease in bundle size. Performance was also paramount. My goal was a smooth 60fps experience on my old budget Android.

Thanks to Gatsby’s code-splitting, the WebGL library is _only_ included in the homepage.

### Homepage sketch

First, I wanted to create a fractal. They have always fascinated me, whether in code or in nature. There are a lot of fractals to choose from in 2D, but in 3D they’re kind of hard. The only one that I could wrap my head around quickly was the Menger sponge.

[![Menger Sponge Fractal](https://alvin.codes/static/ac1c4e9671665213134ce281e92d7959/1c72d/menger.jpg "The 1st homepage sketch: 160 000 cubes forming a Menger sponge fractal")](/static/ac1c4e9671665213134ce281e92d7959/d98c0/menger.jpg)<figcaption>The 1st homepage sketch: 160 000 cubes forming a Menger sponge fractal</figcaption>

After adding a bit of instancing magic, there it was. 60fps and all, except boring to look at. I tucked that code away and turned my attention to another piece of Math & Magic that I had wanted to play with: attractors.

[![The Nosé-Hoover Attractor](https://alvin.codes/static/7144fb4beaf33553520e28d11b9c6f05/1c72d/nose-hoover.jpg "The 2nd homepage sketch: Cubes along a Nosé-Hoover attractor")](/static/7144fb4beaf33553520e28d11b9c6f05/9888a/nose-hoover.jpg)<figcaption>The 2nd homepage sketch: Cubes along a Nosé-Hoover attractor</figcaption>

Despite running at 60fps it “felt” sluggish and became boring to look at.

The final attempt at ~~shoehorning~~ adding 3D graphics to this is what you can see on the homepage now.

## Gatsby wish list

As with most things in development, there were a few surprises along the way, so here’s my wish list for the Gatsby team:

### Become evergreen by default

I wish Gatsby’s relationship with older browsers was an “opt-in” one as opposed to “opt-out.” I prefer a lean website out of the box, with features like Webp enabled and polyfills removed by default. I would rather _add_ backwards compatibility if necessary.

### Disparity in plugin quality

Gatsby makes it easy to find plugins, and to know which ones are maintained by the core team. Despite this, there is a _huge_ variance in the quality of the non-official plugins. I wish more things were parsed out of the plugin repository (like the number of open issues without a response) as some are still referenced despite deal-breaker issues.

### Telemetry

That should **_absolutely_** be disabled by default from the stable release.

I understand the idea, but knowing that a seemingly innocuous CLI might transmit data when I’m not explicitly asking it to is _scary_, and sets a dangerous precedent. The logs may be “anonymised” but doing this is [extremely](https://protonmail.com/blog/truth-about-anonymized-data/) [hard](https://gdpr.eu/data-anonymization-taxa-4x35/) and a waste of time.

If it’s not disabled by default, then “How to opt-out of telemetry” should at the very least be part of the kick-start tutorial (like VSCode does) and not [buried](https://www.gatsbyjs.org/docs/telemetry/) in the documentation. I would even argue that the CLI should ask for again permission every once in a while.

### Final words

On top of everything mentioned above, I wrote scripts, GraphQL queries, and learned about CSS grids, Exif data, and more. I feel like I’ve come out of it as a better coder.