Static content generation
Ian Bicking has an interesting pieces on using static publishing in a CMS. The choice between static and dynamic when building software for the web is a critical one, and one that I think deserves in-depth discussion.
In a dynamic site, pages are assembled “on the fly” as and when they are requested. Most PHP powered sites do this and as PHP as a technology actively encourages dynamic content creation. Generating pages dynamically allows for all sorts of clever applications, from random quote generators to full on web applications such as Hotmail.
In a static publishing system, HTML pages are pre-generated by the publishing software and stored as flat files on the web server, ready to be served. This approach is less flexible than dynamic generation in many ways and is often ignored as an option as a result, but in fact the vast majority of content sites consist of primarily static pages and could be powered by static content generation without any loss of functionality to the end user.
The most widespread example of a static publishing system I’ve seen is Moveable Type, which rebuilds static files for a site each time a weblog entry is added or modified—although it can be configured to serve content dynamically instead.
At first glance, the benefits of dynamic publishing are obvious. What is frequently ignored are the benefits of static publishing, at least for content-driven sites which don’t have any heavy need for dynamic features. The most obvious benefit is performance; serving static files is what web servers such as Apache are optimised to do, and they can do it fast. A second advantage is reliability, as Ian explains:
A big part is that it takes the pressure off of going live. I can be sure before going live that the public website is correct. The actual CMS may explode in flames, but the site will be fine. Going live with a web application is always a stressful process, and anything that reduces the stress of that is a great benefit. As time goes on, static publishing is also a big stress reduction for the system administrator, since a simple Apache configuration is a lot more reliable under different loads and configurations than any dynamic site will be.
I’ve been developing dynamic sites almost exclusively for the past two or three years, but a couple of my most recent projects were static rather than dynamic. These were the LJWorld.com Coupons site and the KUSports.com photo galleries. I wanted to write both of these in Python, because doing so would make the process of transferring them over to our new mod_python powered CMS (currently in development) far less involved. Unfortunately our main production servers don’t currently have mod_python configured, and we weren’t overly keen on setting it up there for the sake of a couple of small projects. Instead I decided to write the administration interfaces using Python CGI scripts, but generate the actual front end pages (which would see far heavier traffic) as static files.
In addition to the performance and reliability benefits, an additional benefit is that static generation provides a simple “staging area” style feature for free. Both the coupons and the gallery interfaces allow users to make multiple changes to site content safe in the knowledge that none of the changes will become visible until the “Publish Site” button is selected. At first I was worried that this extra step could prove confusing, but in practise it allows our content producers to make changes in a safe environment, without fear of accidentally breaking the public site while they are working.
Static content generation certainly isn’t appropriate for every project, but for plain content sites sites that don’t need dynamic features it’s a much more viable option than many people think.
More recent articles
- Weeknotes: Parquet in Datasette Lite, various talks, more LLM hacking - 4th June 2023
- It's infuriatingly hard to understand how closed models train on their input - 4th June 2023
- ChatGPT should include inline tips - 30th May 2023
- Lawyer cites fake cases invented by ChatGPT, judge is not amused - 27th May 2023
- llm, ttok and strip-tags - CLI tools for working with ChatGPT and other LLMs - 18th May 2023
- Delimiters won't save you from prompt injection - 11th May 2023
- Weeknotes: sqlite-utils 3.31, download-esm, Python in a sandbox - 10th May 2023
- Leaked Google document: "We Have No Moat, And Neither Does OpenAI" - 4th May 2023
- Midjourney 5.1 - 4th May 2023
- Prompt injection explained, with video, slides, and a transcript - 2nd May 2023