Static content generation
13th December 2003
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
- Interesting ideas in Observable Framework - 3rd March 2024
- Weeknotes: Getting ready for NICAR - 27th February 2024
- The killer app of Gemini Pro 1.5 is video - 21st February 2024
- Weeknotes: a Datasette release, an LLM release and a bunch of new plugins - 9th February 2024
- LLM 0.13: The annotated release notes - 26th January 2024
- Weeknotes: datasette-test, datasette-build, PSF board retreat - 21st January 2024
- Talking about Open Source LLMs on Oxide and Friends - 17th January 2024
- Publish Python packages to PyPI with a python-lib cookiecutter template and GitHub Actions - 16th January 2024
- What I should have said about the term Artificial Intelligence - 9th January 2024