I recently released a version of the Geo Text WordPress plugin with support for the WP Super Cache and W3 Total Cache page caching plugins. As part of this I added a page to describe why caching plugins are problematic and the different methods the plugin uses to enable compatibility with caching plugins: Geo Text WordPress Plugin: W3TC and WPSC compatibility.
After writing that text, I thought some simple diagrams might help illustrate the reason why standard caching is not useful when you have geo targeted content, and the way that page key modification and fragment caching / dynamic caching can solve this issue.
In the diagrams I’ve used an image of a pair of cogs to illustrate the amount of work the server has to do. The larger the cogs, the more work the server must do, and so the slower the response will be. Bear in mind that when the server must do a lot of work, we’re talking about a response time of around half a second in most cases, but a cached page will be served much faster than this.
With a standard setup, without caching enabled, then the server fully processes the page for each request it receives. This ensures that the content can be geo targeted correctly. However it is not particularly fast and can be problematic if you have a lot of visitors all trying to access your website at the same time.
With a page cache enabled, when a page is first requested, then the server will process the page as normal. But it then caches (saves a copy of) the processed page. On subsequent requests, the server will just send the cached page back. This is much faster as it doesn’t have to process the page again – each page only ever needs to be processed once.
While this works fine for most webpages, it doesn’t work well for geo targeted content. If the first user to visit a page is from the US, then the server caches the page showing the US targeted content. Then when a user from another country visits the same page, they are served the same content, seeing the US targeted page even though they are not from the US.
We can modify the key used for storing and retrieving the cached pages to include the user’s country code. By doing this we cache the page on a per country basis, and avoid the problem of people from one country seeing the content generated for a user from another country. The only potential issue here is that the total number and size of all cached pages will be a lot greater, since you are storing one copy of each page for each country.
If your site had 100 pages and visitors from every country visited every page on your website, then your cache would contain 19,600 pages. That’s very unlikely in practice, but you may well find a 10 – 20x increase in cache size when using geo targeted caching compared to standard caching.
With fragment caching the page will be partially cached when it is first requested. The geo-targeted section of the page is not fully processed before the page is cached. Then on subsequent requests, the page is requested from the cache, and only the geo targeted section will need to be processed.
This is faster than no caching at all, since only a small part of the page (the geo-targeted content) needs processing for each request. However, it is not as fast as using a geo targeted cache, since that does not have to do any processing for each request (other than the first request from each country).
This method is somewhat similar to fragment / dynamic caching, except that the dynamic part of the page is processed in a separate AJAX request. The user first requests the page, and the server partially caches it. After the user receives back the page with the dynamic portion missing, their browser makes an AJAX request to the server for the dynamic part. The server processes the dynamic part, and sends it back to the user. The browser then inserts the dynamic content into the page.
On subsequent requests, the server can quickly respond with the partially cached page. Then a short time later, when the AJAX request is complete, the page is updated with the dynamic content. This means that the user receives the bulk of the page quite quickly, but is likely to see missing or generic content for a second or so before the dynamic content is inserted.
Given equivalent implementations, this is the slowest method of all in terms of time for the page to fully load. But in terms of time for the initial page load it will be faster than Fragment / Dynamic page caching because no processing is needed for the initial request (assuming the page has already been cached).
It can also be faster than Geo-targeted caching in terms of initial page load in certain cases. With Geo-targeted caching, if a person from France visits a page that has only been cached so far for US visitors, then they have to wait for the French version of the page to be fully processed (and cached). Whereas with the AJAX method the cached page is generic, so if a page has been cached for a US visitor, then the same cached page can just be quickly served to the French visitor.
Bear in mind that the above is an overly simplistic representation of each process. If you have late init enabled in your caching plugin, that adds a considerable amount of processing to each request. And using WordPress to serve cached files will always be slower than just having the web server software itself serve them. But I wanted to try and keep it relatively simple without getting too technical.