I Fixed My Website in 317 Effortlessly Easy Steps...After I Broke It
Twenty-two years of design, build, disappointment, rebuild. There is no end in site.
Some of this feeling is just how my brain is wired. More of it is the predominant trend in web design.
This is the story of the latest rebuild on this site, markn.ca, and what I’ve learned along the way.
Everything & The Kitchen Sink
This site has always been some sort of blog. My interests have changed a lot over the years which is why you really only see content from the past few up now.
The oldest post online is actually one from 2011 on phishing for a big return
During that time, this site has been built on;
…and custom builds in;
…and of course, good old Notepad.
I’ve been crafting web sites since the web was a thing and have tried a lot of different approaches to my own site. Partially as part of my continuous learning efforts. Partially to make things easier/cooler for me and my readers.
But, when all is said and done, the requirements for this site are very simple.
I need to display static content and provide some level of search functionality.
Top Tier Performance
Being the nerd that I am, I have always tried to make sure that the site is fast.
- ~0.1 second response feels instantaneous
- <1.0 second responses won’t interrupt a user’s flow
- 10+ second response times are past a users patient to pay attention
For anything I’ve ever published on this site, delivering in sub-second time shouldn’t be an issue.
With this latest iteration, most pages are returned and interactive within a second. And that’s before I’ve done any optimization work.
But over the years, most CMS systems have moved towards more and more dynamically generated content. They build web pages on the fly.
This offers a host of fantastic benefits like personalization, near real-time data ingestion, and more.
Of course, the trade off is that these systems take more resources to run. Given the current state and pricing in the cloud, it’s not a big deal.
It’s a reasonable trade off of developer/user experience for cost.
But it’s always bugged me.
When I started this latest cycle of change, my site was set up as follows;
- Most content built in Hugo
- The output from Hugo (a collection of HTML/CSS/JS) was modified for a few custom scripts for asset optimization and pulling in some 3rd party data
- Synchronize that output (a collection of HTML/CSS/JS) to an Amazon S3 bucket configured for web hosting
To optimize that, I added DNS hosting, content caching, and SSL/TLS from an edge provider.
To add the search functionality, I created the most multi-cloud, multi-technology solution imaginable..by accident.
AWS Lambda function URLs hadn’t yet be released. This mean that Google Cloud Cloud Functions were the lead choice for a simple “request this URL, run my code” type solution.
I configured the Hugo site to output a nice JSON document of all of the content. Fredrik Jonsson has a fantastic post, “Make Hugo generate a JSON search index and JSON Feed”, that was invaluable here.
My custom function, written in C# running .Net core, took that JSON document and indexed it using Lucene.Net. Lucene.Net is a project that started in 2005 (when I first started using it!) that is a .Net port of a Java project started in 1999.
But you what? It works. And it worked lightning fast. Seventeen years allows for a lot of optimizations.
Rounding things out was a function running in the edge provider’s network to smooth out all of the security headers to stitch this all together.
The result? The site was rocket fast 🚀 and provided a great reader experience.
The downside? A very fragile build chain. This worked well on my system but some pieces didn’t work at all when I was writing posts when travelling.
Also, when things broke, I was on the hook. Not ideal.
I Lost Focus
One areas that I’m constantly advising teams around the world on is focus. What is the actual thing you’re trying to achieve? What are the things you’re working that you think are things you have to do get to that goal but actually aren’t?
Quite often, we find ourselves doing work that isn’t actually necessary for us to achieve our goal. We often convince ourselves that this is the best way or will provide the optimal outcome when it fact it won’t.
In an ideal world, that route might produce those results. But how often does that ideal situation actually occur?
Rarely. It happens rarely.
That’s was nearly thirty years of experience all across IT has taught me. 🤣
Of course, despite being well aware of this trap. I still fell into it.
Fixing Things By Breaking Them
In a stunning moment of clarity, I pushed aside my unproductive focus on delivering “clean” HTML/CSS/JS to my audience and shifted my focus back to delivering quality content instead.
That’s not to say that the packaging isn’t important, it is. But only to a point.
Now I know I still wanted to deliver a static site for both performance and security reasons, but how I got there was going to be completely different.
With the desire to finally fix this problem, the last motivation I needed came from an unlikely area. The edge service provider I was using demonstrated unconscionable behaviour which spurred a service change on my part for moral reason.
Not a typical IT migration motivation, but a critical one.
The effort was underway to finally build a more reliable solution to writing and delivering markn.ca.
I F—king Hate WordPress
For a long time, WordPress has stood for everything I don’t like about the current state of the simple web. Mainly because it’s anything but simple.
Yes, the user experience is excellent. Yes, it does a great job of delivering dynamic sites. Yes, it runs 39.5% of websites.
But, I hate it.
Just on the simple principle that a huge number of these sites don’t need that much infrastructure behind them. Because most of the solutions to the slower page construction times is to put more complexity in front of the site.
Because the HTML/CSS/JS output from most configurations of WordPress was never meant for human eyes.
I realize this is a technological equivalent of “get off my lawn,” but it’s how I feel.
Swallowing my pride, I rebuilt this site on WordPress. The experience was wonderful.
I used a number of plugins to optimize all of the images, configure breadcrumb navigation, and even create a static version with a search service to support it.
What bothered me was the ten or so minute deployment time. I would write a post in WordPress and then run a static publication. Once properly configured, this worked seamlessly. It worked reliably.
When I measured the page performance on web.dev, each of the four scoring areas—performance, accessibility, best practices, and SEO—were in the high nineties.
But it took ten minutes each time I made even a small change.
Now, to be honest, I could live with the ten minute deployment time. Especially given that I could use a host of WordPress tooling to write and create interesting experiences for my readers.
But that long deploy time and that
/wp-content/... URL path really, really bothered me. I could probably have lived with that…maybe.
The real problem? I was using four different service providers. There was still too much complexity. Too much operational overhead.
So much so, that I started to look for an alternative to my alternative.
Hugo Back Again
On twitter, there was a ton of great discussion around providers for edge services, static hosting, and more. Netlify kept coming up as a solid option for a complete solution for building and hosting sites.
After mistyping their name a few dozen times, I started to dig through their docs. The documentation itself is clear and shows how each of the features of their platform works together.
At first glance, it seemed like I could build and host a static site with them and then add in a function to handle search. All with the edge services (DNS, caching, SSL/TLS) included.
Taking the CSS adjustments and lessons learned from re-building the site in WordPress, I re-rebuilt the site in Hugo.
It turned out well. I ignored the extra effort.
I only hit one minor technical hiccups that wasn’t clear in the documentation. I reached out to support as the community forums were unclear on a solution. The help I got was amazing and I’ve written that up so others don’t need to stumble through things like I did.
After a week of side-of-desk efforts, I was left with;
- All content built in Hugo
- Images and PDFs using Netlify’s Large Media service
- A search function running on Netlify’s Functions
- DNS, caching, and SSL/TLS provided by Netlify
This is basically what I had before. 🤦
But, now it’s all running in one service and from one git repo. The build chain makes sure that everything deploys properly and caches are updated, etc.
It’s a much more reliable and resilient implementation of the setup that I started with this time around.
Was There A Point?
I’ve put in a ton of work on this site in the past couple weeks to end up…right where I started. Sort of.
The reading experience isn’t that different. Significant improvements were made to the backend and build chain. That’ll make it easier for me to publish more regularly and get back into the flow.
More importantly, I was able to move away from a provider that was simple untenable with my view on the world.
What’s the takeaway for you? Focus on what matters.
That has to be first and foremost the major driving goal. In my case, it’s helping everyone understand security and privacy by sharing what I’ve learned.
The systems and tools that I put in place have to help support that goal. I also have to be flexible enough to adjust as the situation changes.
Sometimes technology will force a refactor. Sometimes it’s external factors.
Anytimse there’s a shift, you need to evaluate your reaction and keep your goal in mind.
…maybe just don’t re-rebuilt things as much as I have. It may not have taken a full 317 steps to get here, but I definitely took a few too many wrong turns.
Hopefully this post will help you avoid that. 😉