Site Owner Tips

Avoid Cache-busting Plugins

Published · Last updated

Traffic spikes tend to hit one or two pages on your site, so to profit from a spike you need to make sure everything on those pages is cachable and that everything is actually being cached. If even one widget forces WordPress to run PHP for every visitor, the whole page drops out of your full-page cache and you lose the benefit exactly when you need it most.

A page is only cachable if it does not contain content that is unique per user. If the same cached HTML is served to everyone, then anything personalised has to be added afterwards in the browser rather than baked into the page on the server. Common examples of unique-per-user content are:

  • Wishlist widget – if it generates its content through PHP (server-side) rather than using JavaScript or Ajax, then it produces unique content per user and prevents page-caching.
  • Basket widget – if your basket widget renders its item count and total with PHP rather than Ajax, then your pages are not cachable.
  • Recently viewed products widget – if this is rendered through PHP then the page cannot be cached, because the next visitor would see the previous user’s recently viewed products instead of their own.
  • Per-visitor pricing – role-based, currency or tax-adjusted prices rendered server-side mean each visitor needs their own copy of the page, which defeats caching.
Why this matters

A full-page cache (Redis, Cloudflare, or a static HTML cache) stores one copy of the page and serves it to everyone. If that copy was built with one user’s basket, wishlist or prices inside it, every later visitor sees that same personal data until the cache is cleared. That is a privacy leak as much as a performance problem.

Performance Tip

Anything that changes per visitor – basket totals, wishlists, recently viewed items, personalised prices – should be loaded with Ajax after the cached HTML has been served, never rendered server-side inside the page. The cached shell stays identical for everyone and the personal bits fill in a fraction of a second later.

Cache-busting plugin blacklist

This list grows as I find more plugins to add to it. If you are the author of one of these plugins, get in touch and I can explain how to make it behave nicely with page-caching plugins – usually it just means moving the per-user output to Ajax.

  • YITH Wishlist – if a page is cached, the next visitor sees the previous user’s wishlist.
  • WooCommerce recently viewed products widget – if a page is cached, the next visitor sees the previous user’s recently viewed products.
  • Simple Ajax Chat – despite the name, it prints user-specific JavaScript inside the PHP page. If you cache that page, the second visitor can talk to admin as if they were the first visitor.

If you know of any more, or have one you would like me to investigate, get in touch.

Best practice

Before you blame a caching plugin for showing the wrong basket or prices, check whether one of your active plugins is rendering per-visitor content in PHP. The cache is working correctly – it is faithfully serving the personalised page it was given. Fix the source, not the cache.

For WooCommerce specifically, the hardest thing to cache is pricing, because it can vary by customer role, currency and tax rules. Super Speedy Ajax Prices solves this by letting you serve a single fully-cached page to everyone and then correcting the prices per visitor with a fast Ajax call, so you get full-page cache speed without ever showing the wrong price.

Further reading

Set up Redis object cache for faster WooCommerce
Add a CDN and edge caching in front of WordPress
Trim scripts, styles and assets for faster loads
Broad practical wins to make WordPress quicker

5 comments

  1. Uriahs

    Why don't you contact the authors and let them know? I'm a little confused as to what you are pointing out in the article. I do use Yith Wishlist and the built-in recently viewed products widget.

    Which caching plugins cause this? What did you use in your tests?

    I can simply disable caching on the wishlist page, but the recently viewed has to be dynamic, are you saying caching plugins usually cause it not to be?

    1. Dave Hilditch

      What I was trying to point out is that there are some plugins which create content on your site unique to each USER or VISITOR. For example - a wishlist basket, that's unique per user. Recently viewed products - unique per user. You can probably think of others.

      These plugins, depending on how they are coded, prevent the use of page-caching because if you cache a page for User A you cannot present it to User B.

      Well written plugins would have the exact same code on the page for User A and User B but would retain a cookie on User A's computer or User B's computer and then JavaScript would be used to contact the server and fetch the unique contents for this user.

      I did try contacting Yith through their support pages - they may have fixed it by now, I have not checked recently, but back when I checked, the advice from Yith was to 'disable your page caching' - hardly a viable approach for a scalable website.

  2. Hakan

    Is it possible to keep cloudflare full html cache or server level cache when someone add a product on his cart?
    Usually it is when cache is gone.
    I use generatepress theme and couldn't find a way.

    1. Dave H. Customer

      Yes, but there's no plugin I'm aware of yet that does this. Some of my clients have custom-built ajax code to make the basket completely ajax driven so the entire page can still be cached. I've had a plan for a while to build a plugin to fix this entire cart issue for high-traffic-spike sites, but I'm still busy upgrading all the plugins I have already!

▲
▼
1/1