The front page of JeremyMorgan.com loads less than a second, most of the time, from various parts of the world.
The website was fast before when it loaded in 3 seconds with the old design. Now it's even better, and I'll show you how I have it set up.
Sometime around 2011, I decided I wanted to move from Wordpress to a static site generator. My reasoning was simple: I write an article, publish it, and it doesn't get modified too much after that. Certainly not enough to justify being served from a database. So it made sense to have a system that would generate an HTML page for each article and serve it up statically.
That move alone cut my load time down considerably. I then became mildly obsessed with page load speed and did many things to ensure it loaded quickly, including:
- Image optimization (Some of the Tools I used)
- Using a CDN for certain assets
I was certainly happy with this setup. My workflow for many years was to create a new article, generate it on my laptop or desktop machine, and SCP the files up to a FreeBSD server running Nginx. It worked that way for a long time. Looking back, that was a crappy workflow, but I only wrote an article every couple of months, so it worked.
I spent a lot of years customizing my installation and contributing code and fixes to the Octopress project.
As much as I loved Octopress at first, and I appreciate all the work from Brandon Mathis and others, Octopress started becoming a huge pain.
The biggest problem for me wasn't Octopress itself, but the Ruby dependency nightmare. I won't go into too much detail, but it became very hard to manage. Octopress required older gems to operate, so as Ruby and certain gems progressed forward, it became challenging to maintain a buildable Octopress installation.
I could no longer build from my laptop because of all the old software I'd have to maintain. I set up a Linux server with old software and used it to build. I then moved things to a container, so I could maintain the old versions of Ruby and those gems to produce the output. For instance, you can't run a version of Ruby newer than 1.9.3.
So I started researching solutions a couple of years ago but never got around to converting things. For a few years, this is what my workflow looked like:
It was ok, but the Achilles' heel in this operation was always the Octopress build, and I knew it. Maintaining all that old software for a simple build step was easy as long as I didn't touch anything.
Last month, my server failed. The server that was building the Octopress images. So I spun up another server, installed Docker and the container and it wouldn't work. I tried everything I could think of, and the fact was clear.
I could spend hours upon hours building another container with ancient software to make Octopress work, or I could spend that time changing to another CMS.
So I started seriously evaluating options for another static site generator.
I spent a lot of time evaluating different options. I will go into more detail in a future article, but it came down to these:
- Static file generator
- Must build fast
- Must be easy to customize
- Must be portable (Mac, OSX, Linux)
Now the last one might seem a little silly, but I never know what platform I'll be on when I'm writing. I might be on a Mac, Windows, or Linux, depending on what I'm writing about and where I'm taking screenshots. I want to build and view the page locally before pushing to dev, and eventually production. So this was important to me. But here's what I found after a lot of evaluation:
All of these static file generators met these needs.
So that made the choice difficult. I got a version of JeremyMorgan.com up and running with all three of these generators on all of the platforms no problem. I was able to customize things, and they all built pages quickly. But I had to choose one.
Pelican is dependent on the Python ecosystem, which is much less flaky, so it was a close second place. Hugo, however, builds from an executable. So even if it gets abandoned or dependencies start to break, I can always just use the executable to generate the site until I find an alternative.
That's why I chose Hugo. It has a simple layer of protection against dependencies getting away from you. Not everyone cares about breaking changes and backward compatibility. Projects get abandoned, and that's part of the price you pay for open-source software. Hugo is portable, simple, and written in Golang, so I could just fork it or modify it if it gets abandoned. I've been pleased with my choice.
The next question was where to host it. When my server crashed, I decided to take my static files and move them to an Amazon Lightsail setup. It was super easy and quick, but I knew that another hosted server wasn't going to be the best setup.
There are few reasons in 2020 to set up an entire Linux server to host a static website.
My requirements for a hosting setup:
- Must be fast
- Must be secure
- Must be something I can deploy easily
So I examined my options. Here's what I considered:
I started putting together servers and doing tests. I found that hosted web servers simply could not keep up with the speed of AWS or Netlify, no matter how I optimized them. This is partially due to edge servers. I tested my speed from the following locations:
- Portland, OR
- Dulles, Virginia
- Orlando, Florida
- Dallas, Texas
- San Francisco, California
- Sao Paulo, Brazil
- London, UK
- Rose Hill, Mauritius
I did spot tests from all over the world, but these are the cities I focused on the most. I wanted to see what would be overall fastest out of all of them. I chose a page with lots of text and images on it. I was surprised at the results.
The hosted FreeBSD server and IIS server were fast, but not in the same league as Netlify and AWS once I left the United States. I want things to be fast for all of my website visitors not just the ones near me. That was a big consideration for me.
Netlify was the speed winner in almost every region.
After a long run of tests during all different parts of the day, Netlify came out as the winner. AWS Amplify was close. If I spent a ton of money on prime AWS assets, I'm sure I could beat the scores, but I don't make money off this website, so that's not an option.
So looking at my requirements, Netlify met them all.
- It's fast (the fastest)
- It's secure (from all the information I've found)
- Workflow is incredibly easy.
With Netlify, I connected my Github repo to it. I can commit to any branch to store changes. I can commit to a dev branch that I can push it to a preview. When I push to master, it's automatically published to JeremyMorgan.com.
Here's why this site loads so fast.
- It's not as cluttered as it used to be
- I'm using minimal CSS and elements
- Optimized JPEG images
- It's minified before publishing
- Netlify is really fast and serves it fast everywhere
So that's my secret sauce. The combination of these items means my site loads in under a second on the main page, and pages with heavy images and text come in around three seconds. Super fast.
My site loading quickly is important to me because of the purpose it serves. I provide tutorials and information about development, and I don't want people to have to wait to see it. I want it to be available in countries with poor internet access. Hugo and Netlify help me achieve that goal.
If you'd like to set something like this up and have questions feel free to contact me, and I'll share what I know.
I'm not done optimizing the speed of this site and I'll share more tips in the future!