Introduction

In optimizing large WordPress Websites for performance I always look at caching certain parts of the Website, mostly (of course) those that require a lot of Queries/calculation.

For the Caching of the WordPress menu I usually use a function like the one I posted as an Answer here.

This function checks if there is a transient containing the menu-HTML, and if it exists, delivers the HTML from the transient. If it does not exists, the menu is build and the transient set. To be clean, I also hook into wp_update_nav_menu to clean the transient as soon as the menu is saved, to always have the latest version available.

So far so good.

This technique works very good and gives a great performance boost, especially if the menu contains a lot of entries.

The Problem

Now, some months after developing this method, I ran into a problem, and feel stupid for not thinking about it in the first place.

Menus are different on different pages

Depending on what Page is called, wp_nav_menu delivers different HTML Code. current-menu-item and classes like that are of course applied to the menuitems.

So the problem is, what is the best way to cache the menus and still have the correct classes available for each specific page?

I thought about two versions

  • adding the classes via jQuery, which results in more calculating on the Clientside
  • caching the menus for each ID seperatly, resulting in quite some Databaseload, if the page has a lot of menuentries

However, I tend to use the second option. Do you have any concerns with caching that much HTML as Transients?

1 Answer
1

There is no generic solution for this problem: The same menu can be rendered with different walkers on different pages, or plugins change the menu on some pages.

You could extend your script to evaluate the differences to an untouched menu and build the necessary JavaScript on the fly … and cache that too … for each single page.

I don’t think it is worth the hassle. getting all the edge cases right is hard work, and the menu would still be different for users without JavaScript (search engines, unresolved script errors etc.).

Leave a Reply

Your email address will not be published. Required fields are marked *