humanmade / nav-menu-cache

Cache WP Nav menus. Designed for use with Human Made's WP Redis.
GNU General Public License v2.0
2 stars 0 forks source link

Investigate ways to improve this plugin #3

Open mattheu opened 1 year ago

mattheu commented 1 year ago

From @rmccue on Slack:

The expensive part of menus really is pulling the data, not building HTML, so object caching is really a better solution; fragment caching is just the easier way

This plugin currently just fragment caches the rendered HTML, and this has to be cached for each URL in order to support classes such active menu items and active menu parent.

Some possible areas for improvement.

rmccue commented 1 year ago

To clarify this in a slightly longer format: we build much more complex HTML all the time and it doesn't have any performance problems. The problem is querying the data out.

Basically, menus are a graph (in the mathematical sense), similar to comments; that is, they are hierarchical, and pulling the data requires traversing that graph.

graph LR
  Home
  --> services["Services & Solutions"]
  services --> Consulting
  services --> Valuation
  services --> digital["Digital Solutions"]
  digital --> Overview
  digital --> Software
  Home --> sus["Sustainability"]
  sus --> sus_over["Sustainability Overview"]
  sus --> sus_consult["Sustainability consulting"]

At least traditionally, WordPress did this in a very terrible way for performance, although I believe there have been at least some improvements. In any case, the full data for each of these nodes is the same on every page and can be cached, except for the $current_page === $id check. Looping through every node and generating the actual HTML should be cheap (you can iterate 10,000 array items basically instantly, a couple hundred nodes shouldn't be free).

Fragment caching is most useful when you have a single stable key with content that's the same across many pages (so page caching would be ineffective) and where it's a pain or expensive to cache the data (so direct object caching would be ineffective). IMO, nav menus aren't a great fit for that unless you can eliminate the active page indicator, but then you have to worry about what you use as the key for the fragment cache.