If you just want to see the final code, scroll about half way down, otherwise stay on for a bit of a babble first... 📣
On the whole, FlatPress is not terrible in terms of performance and I haven't had many issues with it. However lately I have been noticing some stability problems as my Blog increased in popularity and the number of posts grew. Things like corrupt indexes, resetting post view counts, slow response times, etc. And then, I wrote a story which catapulted my traffic volumes to 50x their usual. And my server went down. Not once, multiples times, there were several hours of excruciatingly slow page loads and people resorted to using Archive.org copies of my story. That's when I knew I had to do something.
Caching Generated HTML
My first thought was to use memcache to keep generated HTML pages in memory and serve those instead of generating HTML every time a blog post was requested. Simple idea, but I didn't want to go through the motions of setting up memcache in MAMP. So I fell back to using APC as it required no setup and I knew that I could enable the APCU extension on my webhost.
Looking at index.php, I could see that the Smarty::display() method was used to render and output the content of a page/post. Simple but effective and I thought I would be done with this very quickly.
The trick was of course to switch to the Smarty::fetch method, cache that output, and serve cached output as required. The cache key was based on $_SERVER['REQUEST_URI'].
Well that approach worked. In a way. However, it only worked in the case where I was caching blog post pages. Everything else like category listings, the home page, sitemap, etc were only partially cached. For some reason only part of the HTML was being generated by Smarty and the rest - well it was being sent to the browser from some other part of the code (I didn't track down where exactly, I did look and what I found were horrors so I stopped looking 😅).
Adding a Cache Handler to Smarty
So then I decided to try a different approach by implementing a Smarty Cache Handler that would work transparent to FlatPress and at least in theory I would not have to worry about the rest of the code base. Well the cache handler worked...for blog post pages only. This indicated that FlatPress was doing something bad deep inside its core. Back to square one.