Can my tools build tools? Pre-rendering web pages with help from ChatGPT
We're all trying to work out the implications of generative AI. We've all seen examples of it building websites and coding a version of the snake game. These seem impressive until we realize there are millions of websites and thousands of versions of snake, so it's not too surprising tools like ChatGPT can regurgitate them. After all, it's easy to replicate something that's well-understood?
How about a more interesting challenge? How well can these tools build something new? I decided to give this a try. I needed a tool to use with my blog site, davehudson.io. How well would ChatGPT be able to help?
A quick aside
Humans have a long history of building tools. About 2.6 million years ago, in the early Stone Age, our ancestors began creating simple stone implements to aid in hunting, gathering, and daily survival. I daresay stone engineering was quite satisfying at the time, but these days our most prolific tool builders are software engineers.
Most software takes the form of tooling. It's intended to be created once and used many times. We could almost say software engineering is the pursuit of finding ways to build ever better, more reliable, and less expensive tools.
The problem statement
I’ve been rebuilding my blog site (formerly hashingit.com), and this time I decided to do it from first principles. I like to do slightly mad low-level things sometimes!
The blog site is a single page app (SPA) and is 99% TypeScript code (we'll save discussions on why for another time), but I realized that doesn't play nicely with web crawlers, or social media sharing. As I'd like people to find things I write, and potentially share them, I needed to come up with a way to serve up initial static versions of any page on the site before the TypeScript code could take over.
First steps
As I’ve increasingly done for the last 6 months I asked my sidekick, ChatGPT, how to solve this problem. It suggested I needed to pre-render these pages.
It also recommended I should follow the crowd and serve up the pre-rendered pages to crawlers and bots but serve the dynamic version to humans. While apparently common practice, that seemed a bit clunky, so I decided I'd serve the static version to everyone but then let the dynamic code take over after that first page load thus any first page is the only page you “load”).
It next, helpfully, identified some projects or commercial services that might do what I needed, but my intuition was I could do something local, fast, and free (except for my time). Being able to work offline was a bonus because I spend a lot of time on trains and planes and Internet access is awful on both.
30 minutes and code
Here's my initial prompt in a new session:
How do I use google chrome to pre-render my single page app website?
And the first reply:
Pre-rendering a single-page application (SPA) using Google Chrome involves generating static HTML content that can be served to search engines and users to improve SEO and performance. Here are the steps to pre-render your SPA:
1. Use a Pre-rendering Service
Pre-rendering services can handle the task for you. These services visit your SPA, render it using a headless browser, and save the resulting HTML. Popular services include Prerender.io, Rendertron, and others.
2. Use Headless Chrome with Puppeteer
Puppeteer is a Node.js library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Here's a basic example of using Puppeteer to pre-render your SPA:
...goes on to give some code fragments.
I like to build things - option 2 was the only way to go!
The chat went on for about half an hour with me asking questions and suggesting things I'd like to see, and with ChatGPT writing all the code. We ended up with this version:
It has a few rather quirky features because I wanted to render my site using a local express.js
server and not the one that hosts my live blog, so it does some translation of the sitemap.xml
file to find the correct URL to render.
Let's make this more interesting!
We could almost declare victory at this point. To render 29 pages took 47 seconds on my M1 MacBook Air.
I'm fairly impatient though, and hate waiting for builds. So, I upped the ante a little and asked for a parallelized version. A little back and forth and we ended up with this:
This one could complete in about 12 seconds. Now we were getting close to what I wanted! A manual tweak to run 16 in parallel and rendering was just under 6 seconds. I'll take that as a huge win!
Total elapsed time - about 2 hours.
A sign of things to come
Just like a human engineer, ChatGPT made mistakes. It needed dialogue and questioning to keep it on the right path, and it worked better if you could give it a way to assess if it's doing the right things (that's a subject for another time).
As the code got longer, it was also a little irritating in wanting to give me all the code all the time, when I only wanted a small section changing.
However, I got an effective solution to my problem in 2 hours rather than 2 days. Left unassisted, I'd have probably still be reading docs at the 2 hours point.
This was seriously impressive.
I've been building software for a very long time. That included many years building compilers and code generators, and it's very clear we're somewhere we've not been before.
I read Fred Brooks', “The Mythical Man Month” almost 30 years ago. “No Silver Bullet - Essence and Accident in Software Engineering” was the chapter that has resonated with me for all that time. It posed that in the 10 years after it was written there wouldn't be a single technology that would give a 10x improvement. That has remained true for almost 50 years. I have a feeling that 10x barrier may finally be about to break.