This blog used to be generated by Fugitive, a static blog engine1 backed by git. Fugitive is very neat and minimalistic, but it is also written in pure sh, and its design makes it spawn a lot of processes, which makes it unacceptably slow for me.
Rather than rewriting a similar engine with a different design, I chose to migrate to Pelican, a more common static blog engine in Python. I hoped that this would be simpler than rolling my own. It still took several hours to set everything up correctly, rewrite the templates, understand the way it works, etc. However, everything should be fine now, and very little should have changed relative to the fugitive version. I hope nothing subtle broke in the process.
In terms of performance, pelican takes about 2 seconds to recompile the entire blog, as opposed to around 30 seconds for fugitive to recompile one page (most of which in spent compiling the archives page), and far more to recompile all pages when templates have changed. (This being on fairly recent machines.) It also looks like pelican's processing time comes from the constant overhead of loading its own files, rather than from the blog size; I guess time will tell. The new setup also separates neatly the git versioning of the blog source from the tools used to generate it, rather than relying on fugitive's hooks which I always found a bit too brittle for my liking.
As an added benefit, I have set up some elaborate things which I had never taken the time to configure with fugitive: using markdown to write blogposts, having syntax highlighting in code snippets with Pygments, math rendering with MathJax, footnotes, etc. Categories, tags and languages should also be easy to set up if needed.
Pelican does have a few downsides: it is a bit complex to understand and heavy, it requires separate plugins for various things, which you also have to install. Most of its complexity is because it is too generic for my needs, and its config tries to abstract away things which I'm OK with hardcoding (e.g., in the templates). Also, pelican does not interact with git at all, and it is a bit silly that article creation and modification times must be recorded as metadata in the articles whereas they are available from git. I intend to rely on simple scripts to save me from having to add this kind of info in files by hand.
A static blog engine is one where the entire blog is generated on my side to HTML files, and the files are then uploaded to a vanilla HTTP server; the HTTP server is unaware of the logic of the blog. I prefer this because it saves me from having to configure a fancy Web server, and allows me to write blog articles on my own machine with a real text editor, rather than writing them in-browser on the server as is typical with dynamic blog engines. ↩