When I enabled nicemenu on my site, every page was getting rendered very slow. I also looked at quries using devl module and thsoe have increased by about 90 per page? Does the module queries the whole menu tree per page, even though it is not expanded? Shouldn't it catch the expanded tree and use it for subsequent visit from user? When I turned the module off the performance returned to normal.
IS this strange or other folks have seen this behaviour?
Comment | File | Size | Author |
---|---|---|---|
#8 | 350755_nice_menus.diff | 4.64 KB | dalin |
Comments
Comment #1
add1sun CreditAttribution: add1sun commentedI personally don't notice any slowdown, but I suppose it will vary by site, how big your menus are, etc. Yes it gets the whole menu tree even if not expanded, since it needs to build the full menu in HTML in order to function.
The problem with caching menus is that they can change per user or per page or both, depending on the use. In Drupal 5 there is no core block cache, so you would need to use the block cache module to cache the NM blocks. A related Drupal 6 issue (where core block caching does exist) is here: #284294: Attribute 'cache' should be set in blocks definition
Comment #2
add1sun CreditAttribution: add1sun commentedNo response - closing.
Comment #3
dalinYes there is a HUGE performance issue with Nice Menus. Most noticeable on sites that use node access and thus cannot use block caching. The problem being that Nice Menus loads the whole menu tree. This in turn causes any Views that are menu items to load. Nice menus added 500+ queries and > 3 seconds to my page generation times.
I'm guessing that there may be a cleaner way to do this (or maybe not in D6). The problem being that the menu system is not well documented.
As a workaround I did added the following theme override:
This will cache the whole thing for all users. It will get regenerated on each cron run. You may need to alter accordingly for your site.
Comment #4
ISPTraderChris CreditAttribution: ISPTraderChris commentedI recently started analyzing my site with the XHProf PHP profiler. Guess what I found? The number one resource hog (in cpu ms) was - much to my surprise - Nice Menus. It seems a bit silly that there is no built-in caching options for a module that has the potential to add seconds on to page-load times. The sacrifice for caching should really just be the inability to know which menu option is the 'active' menu. But, quite honestly, I wasn't relying on this feature anyway as its a bit awkward to try and note the active menu item when dealing with DHTML drop down / out menus.
This is my vote for a config option to enable caching with the caveat that you lose any accurate identification of the 'current' menu item. It would seem to me that caching should be performed on a menu+direction+uid basis. I've seen some mention that caching would have to be per-user per-page but I honestly do not understand the need for the per-page piece if we are rendering the entire menu tree anyway.
Right now we are running a variation on dalin's theme override code (above) as follows:
This currently lives in our theme's template.php file -- though would be nice to have it added to the module. If there is a willingness to commit it, I would be more than happy to submit a patch.
Comment #5
ISPTraderChris CreditAttribution: ISPTraderChris commentedThe code in my posting above has a few omissions - should be:
Comment #6
anonymous07 CreditAttribution: anonymous07 commentedSubscribe
Comment #7
add1sun CreditAttribution: add1sun commentedIf someone wants to supply a patch against Drupal 6 V2, I'll give it a look. I don't need this myself and I am certainly not going to do this for the D5 version. If no supplies a patch, I'll move this to a docs issue so folks can have it as a reference when searching.
Comment #8
dalinOK, I think this patch results in the lowest number of cache entries while still being as flexible as possible.
Comment #9
stacysimpson CreditAttribution: stacysimpson commented++++++++++++++++++Ship it!!!
We have a large menu structure and complicated access controls. The patch in #8 alone reduced an example page load time from 3018.07 ms to 1405.6 ms.
Comment #10
doublejosh CreditAttribution: doublejosh commentedIf you place your primary links into the header region via a block (and remove $primary) from your page.tpl.php then you can cache the block smarter using Block Cache Alter (set by role, by user, by page, etc.)
Also I would recommend breaking it into two menu block so that one can be globally cached and another can be based on the user, then just place the two menus side by side.
Comment #11
podaroksubscribe
waiting for release
Comment #12
podarok1.7% speedup on /user page for anonymous user on a large site
w/o patch
w patch
Comment #13
vordude CreditAttribution: vordude commentedThanks for you work on this caching.
I appreciate the benchmarks, What's with all of the failed requests? I'm not ready to make a call based on that just yet.
Also the patch is making a cache key times every menu * every user id, that will add a ton of writes to a busy site.
How about handling this at the Block level? Currently it's set to BLOCK_NO_CACHE, and there may be an easy win to be had there.
Based on the code comments, this was avoided in the past because menus can be so different for different users.
Comment #14
dalinThe failed requests in the benchmark are _probably_ fine - note the cause - length. This will happen if either the HTTP header or HTML document differs by one byte. To confirm run wget twice on the page and diff the two.
See Add1sun's remarks from #1 "The problem with caching menus is that they can change per user or per page or both, depending on the use." Also any busy site will either be already experiencing this issue, or be using block caching and thus this would not experience tonnes of writes. For a menu of even moderate size, writing to the cache once per user per menu is faaaar cheaper than rebuilding several views on each page load. Putting this patch into place will greatly improve the situation for 99% of sites. For the 1% that may be adversely effected by high cache writes I see two options:
1) Include a setting at admin/settings/nice_menus to allow the admin to choose caching options. Flexible, but challenging to do in a way that is not confusing to the hobbyist, while still useful to the enterprise site.
2) Same as #1, but don't have a setting on the admin page. Just use variable_get() and make a note in README.txt to direct advanced users where to go.
I'm kinda partial to #2.
Comment #15
podarokdifferent size in benchmarks are result due some profiling code from xhprof, so - nevermind
Menu is small in my website version, so possibly we need to test huge menus with many items against this patch
Comment #16
lpalgarvio CreditAttribution: lpalgarvio commentedajax it.
Comment #17
rjbrown99 CreditAttribution: rjbrown99 commented+1 the caching patch was quite helpful to me. I'm running with it now in prod.
Comment #18
tim.plunkettFixing tag.
Comment #19
stacysimpson CreditAttribution: stacysimpson commentedJust ran across this thread again. We started running with this patch originally; however, this cached information doesn't have the ability to get cleared on node actions (I.e. add/edit/delete). We switched to using block caching and receive similar performance benefits.
HTH.
Comment #20
dalinYes I suppose if you are linking to nodes in the menu that would be the case. In that case switching from cache_menu to cache_block would do the trick. I'm not sure that we can assume that the cache_block cache bin exists though.
Comment #21
stacysimpson CreditAttribution: stacysimpson commentedTo clarify, I meant to say that we reverted this patch and are only using block caching (block cache alter) at the moment.
Comment #22
deviantintegral CreditAttribution: deviantintegral commentedSo, it sounds like we can avoid having to change the module and just point to Block Cache Alter in the README. Sound good?
Comment #23
rwohlebBlock Cache Alter won't help you if you rely on $primary_links. We still need a better solution.
Comment #24
anarcat CreditAttribution: anarcat commentedAnd what about block-level caching? What is wrong with *not* hardcoding it? I am not sure I understand the problem with $primary_links vs block_cache_alter...
Comment #25
anarcat CreditAttribution: anarcat commentedThis simple patch may help people a lot, but may break other sites.
Maybe it should be part of the nice menu configuration to choose how it is cached? That would site well in nice_menus_block_configure...
Comment #26
gstout CreditAttribution: gstout commented@dalin Will your patch in #8 work for D7. I'm still seeing bad performance from nice menus.
Comment #27
apadernoI am closing this issue, since Drupal 4.x, 5.x, and 6.x are now not supported.