I have a site with 13 different menus and around 1400 nodes. I'm trying to load the context UI, but it responds very slowly. After enabling devel query information and the page loads, I get: Executed 6166 queries in 91405.41 milliseconds. The majority of the queries come from 4 different function that repeat over and over many times:
drupal_lookup_path:
SELECT dst FROM url_alias WHERE src = 'node/1126' AND language IN('en', '') ORDER BY language DESC, pid DESC
taxonomy_node_get_terms: <-- this one is the slowest going over 5ms every call
SELECT t.* FROM term_node r INNER JOIN term_data t ON r.tid = t.tid INNER JOIN vocabulary v ON t.vid = v.vid WHERE r.vid = 1126 ORDER BY v.weight, t.weight, t.name
cache_get:
SELECT data, created, headers, expire, serialized FROM cache_content WHERE cid = 'content:1126:1126'
menu_link_load
SELECT m.*, ml.* FROM menu_links ml LEFT JOIN menu_router m ON m.path = ml.router_path WHERE ml.mlid = 5108
node_load
SELECT n.nid, n.type, n.language, n.uid, n.status, n.created, n.changed, n.comment, n.promote, n.moderate, n.sticky, n.tnid, n.translate, r.vid, r.uid AS revision_uid, r.title, r.body, r.teaser, r.log, r.timestamp AS revision_timestamp, r.format, u.name, u.picture, u.data FROM node n INNER JOIN users u ON u.uid = n.uid INNER JOIN node_revisions r ON r.vid = n.vid WHERE n.nid = 1130
What exactly is going on here? Any ideas on how I can get bearable performance when using the UI?
Comments
Comment #1
Steven Jones CreditAttribution: Steven Jones commentedDo you have to use the vocabulary with context? You can turn off per vocab which ones appear in the Context UI from the vocab settings pages.
Context UI will probably be a little slow with lots and lots of menu items, but you don't have that many.
Are you seeing lots and lots of node loads then? Context UI should not be loading nodes in the UI.
Comment #2
bkildow CreditAttribution: bkildow commentedI would prefer to us the vocabulary with context for my situation. I am checking if a node has a specific vocab term set, and displaying a block and adding a body class based on that condition being met.
I was able to create a work around for myself (albeit not very elegant or recommended for anyone). I have commented out two blocks of code in context.core.inc. One in the context_context_conditions() function; the if block that checks if the menu module exists. And then the accompanying if block in the context_context_reactions() function.
It seems that the performance issue is related to the Active Menu condition and reaction. Specifically, after doing some profiling, it seems within context_context_reactions(), menu_link_load() gets called for almost ever menu item. From this function _menu_link_translate() is getting called. From this function _menu_load_objects() is calling node_load from there taxonomy_node_get_terms().
This may actually be a result to something wrong with my menus and not the context module. I actually created a module to help me migrate menus from a different CMS. Everything appears to be correct, but I don't claim to be an expert on the menu system. One thing I have noticed is the router_path for all my menu items is node/% and load_functions include node_load and access_callback is node_access. This appears to be consistent if I generate a menu item using my custom module, or create a node manually and is why the chain described above is being called.
I'm wondering if setting my router_path to "node" would fix the issue since it uses user_access as the access_callback and there seems to be a special condition in the menu module to help performance. I not sure what the relationship is between "node/%" and "node" within the menu_router table, or what the ramifications of doing that would be. I guess it is time to dive deeper into how menus work....
Comment #3
Steven Jones CreditAttribution: Steven Jones commentedNot sure if we can load the menu items in a 'better' way, or if this is just basically a bug in Drupal core.
Comment #4
Steven Jones CreditAttribution: Steven Jones commentedComment #5
myers_d CreditAttribution: myers_d commentedI just ran into the same issue. I have 14 menus with about 60 items in each. Context UI chokes and dies unless I give PHP 256MB Ram and a script timeout of 90 seconds. I also tried to track down the problem. It appears that the core Menu module tries to cache the menu tree so it loads faster on subsequent requests. This SHOULD make it go faster, but I think it may be storing that array in memory multiple times. Oddly enough, it's not a lot of data, so it shouldn't be much of a problem. I'll poke around it a bit more and see what I can dig up.
Comment #6
EndyBoooj CreditAttribution: EndyBoooj commentedSame here. We don't have a lot of menu's but a lot of nodes (+2000 to be exact).
In our situation it would be handy if we can set in the settings which menu-trees should be loaded or which to ignore.
Our navigation menu holds 95% of all our nodes so this feature would be nice.
Comment #7
marcushenningsen CreditAttribution: marcushenningsen commentedI'm having the same issue. Also checked with the devel module, and it seems that the menu_link_load is the one causing problems. I only have a handful of menus, but I have a big number of nodes.
Comment #8
marcushenningsen CreditAttribution: marcushenningsen commentedI actually meant to change to 3.0. This is the version in which I'm experiencing the problems.
Comment #9
marcushenningsen CreditAttribution: marcushenningsen commentedChanging title
Comment #10
wojtha CreditAttribution: wojtha commentedI ran into the same problem today. I have very small menu (around 300 links in menu tree including administration menu, I have 50 links in primary and secondary links in total) and I found that menu_link_load is called 600 times on one page.
menu_link_load is used in following places in Context:
1. context_condition_menu.inc
2. context_reaction_breadcrumb.inc
3. context_reaction_menu.inc
In my case all load was caused by context_condition_menu.inc. I found that menu_link_load in context_condition_menu::condition_value() is fired 600x times and twice for each link.
So in the first step I added static caching which reduce DB load from 850 queries to 600 and in second step I decided to rewrite the condition_value() method completely. So now, I'm on 200 queries, since I'm using menu API more effectively. I basically took menu_parent_options and rewrote it to return same values as is needed by context_condition_menu, because raw menu tree data contains link paths too so it is ridiculous to load all menu link paths one by one...
Comment #11
wojtha CreditAttribution: wojtha commentedbump
Comment #12
picco CreditAttribution: picco commentedBumped on to the same issue, i'm using admin/context combination so i'm implmenting a context editor on/off switch leaving context editor disabled most of the time...
Comment #13
wojtha CreditAttribution: wojtha commented@picco could you please test my patch?
Comment #14
hefox CreditAttribution: hefox commented#1216178: Huge performance hit without static caching is a duplicate; I wonder if it'd be better to have ctools, which is a dependency of context, would have a helper function or perhaps the helper function should be in it?
Comment #15
jameria21 CreditAttribution: jameria21 commentedWe had this same problem, except in Features, but the culprit was the same function. We ended up making a patch for features to create a new function that still does what we need it to, but is more efficient.
Look at features.menu.inc at the function menu_links_features_export_options(). Maybe this will give some insight.
function menu_features_link_load($mlid) {
if (is_numeric($mlid) && $item = db_fetch_array(db_query(
"SELECT m.path, ml.router_path, ml.mlid, ml.menu_name, ml.link_path
FROM {menu_links} ml
LEFT JOIN {menu_router} m
ON m.path = ml.router_path
WHERE ml.mlid = %d", $mlid)
)){
return $item;
}
return FALSE;
}
Comment #16
Anonymous (not verified) CreditAttribution: Anonymous commentedIt's not just slow, to my opinoin it's also a resource hog. I had to increase my PHP memory limit to 256M just to use the UI. I think some things should be "cached" instead of loaded each time.
Comment #17
Anonymous (not verified) CreditAttribution: Anonymous commentedIn my case (with 200K taxomony terms) I should disable the taxonomy feature. But in D7 there is no option to do this. I edited the context.plugins.inc and comment out the sections for
- context_condition_node_taxonomy
- node_taxonomy
I suggest an option on the setting pages "choose which condition to enable/disable", so you can easily limit what you need. Maybe same for reactions.
Comment #18
Fabianx CreditAttribution: Fabianx commentedNeed to attach new code for 7.x
Comment #19
rjbrown99 CreditAttribution: rjbrown99 commentedHave any of you tested patch #10, or the patches from #1216178: Huge performance hit without static caching? What say ye in terms of the best approach for now?
Comment #20
Fabianx CreditAttribution: Fabianx commentedI have tested #10 and it did no longer apply.
The best approach is to make use of the already cached menu by the default get_parents().
This patch does this by re-implementing as less functions as possible.
Best Wishes,
Fabian
Comment #21
atlea CreditAttribution: atlea commented@Fabianx: Wow! Patch seems to work great. I have only tested, not really reviewed, the patch - but it sure did speed up context ui on a site with 10k+ nodes. From 20-30 second load times down to 5. Thank you!
Comment #22
Fabianx CreditAttribution: Fabianx commentedSeems to work, but needs review by the community.
Comment #23
Cameron Tod CreditAttribution: Cameron Tod commentedWorks great here, it's made a huge difference for us and seems to be trouble free. I see no issue with the style. I'm going to be bold and mark it RTBC :)
Comment #24
Fidelix CreditAttribution: Fidelix commentedIt worked for me. Semi-fresh Drupal.
Comment #25
Cameron Tod CreditAttribution: Cameron Tod commentedWe've deployed ~20 big sites in the last 2 weeks with this patch applied, without any issues and with a lot of context.module use. I'm keen to see it committed!
Comment #26
ChaseOnTheWebAnother affirmation for the patch. Our site has 300+ contexts and dozens of menus with a few items in them. This patch took context_ui from timing out after 90s/maxing out 384M memory to being quick and responsive. No side effects to report from our team after 2.5 weeks in use.
Comment #27
amanaplan CreditAttribution: amanaplan commented+1 to commit. Worked great for us. (Our site has roughly 100 contexts, 70 menus, and 2,500 menu items and the unpatched context constantly timed out)
Comment #28
corvus_ch CreditAttribution: corvus_ch commentedI also can confirm.
On a system with the Context UI Editor enabled in the Admin toolbar of the Admin module, this gives me e performance boost of around ten seconds (rendering time before: 30s, after: 20s). See #1787762: Contex UI editor block in combination with admin makes system unusable slow
Comment #29
firebird CreditAttribution: firebird commentedRegarding the patch in #20:
The if-clause in the beginning of context_menu_parent_options() that causes an early return is not necessary, and it's causing some problems for me.
The early return option is there so that people can implement their own versions of getting menu parent options, in case the default implementation isn't fast enough. This has now been done with context_menu_parent_options(). The early return option is unnecessary in the better performing version.
I'm the maintainer of a module called Menuperformance (http://drupal.org/project/menuperformance) that deals with very similar problems. Currently, Menuperformance isn't compatible with Context, since Menuperformance doesn't implement an alternative menu option selector for Context. With the patch in #20 (with a small change), Menuperformance wouldn't need to do anything.
The only problem is the early return if-clause left in the patch; As Menuperformance is based on setting that exact variable, the current version of the patch still isn't compatible. If the early return option would be removed, the modules would play nicely together.
Here's a link to the original issue that got me here: http://drupal.org/node/1810004
Comment #30
Fabianx CreditAttribution: Fabianx commentedThen we go back to CNW. I'll roll a new patch.
Comment #31
steinmb CreditAttribution: steinmb commentedCross posting and coming from #1810004: Conflict with context module.
Comment #32
gunwald CreditAttribution: gunwald commentedI have the same problem with taxonomy terms. On my site I have more than 500 k of them and that makes it impossible to use the Context UI: The memory limit of 512M exceeds. Why is it necessary to get all terms just to show the UI?
Comment #33
kristygislason CreditAttribution: kristygislason commentedThe patch in #20 is working for me. I am seeing extreme performance improvements. From over 30 seconds load time to less than 5 seconds. I have been getting "Fatal error: Maximum execution time of 30 seconds exceeded" without the patch applied. I am not using the menu performance module mentioned.
Comment #34
paolomainardi CreditAttribution: paolomainardi commentedI think would be nice to have an option to choose which vocabs and menus to display on context condition page, as the features module do.
What do you think about ?
Comment #35
dasjoattached is a hack that just removes
context_condition_menu
,context_condition_node_taxonomy
andcontext_condition_taxonomy_term
for environments that don't require those conditions and would like to use the context ui without the described performance issuesComment #36
steinmb CreditAttribution: steinmb commentedas @paolomainardi mention. This should be configurable. If we look at features 2.x. It got a setting for what features to expose and this is mostly done due to speed listing all exportable components.
Comment #37
bowersox CreditAttribution: bowersox commented+1 for fixing this in the Context UI module.
We have a site with ~800 menu links, and loading the admin form /admin/structure/context/add requires a ~120-second page load wait. We drilled in and found all of this time is happening in the condition_values() function inside context_condition_menu.inc. The function loops over all menus, and calls menu_link_load() for every menu link. That is hugely expensive on CPU and database queries.
In my opinion, the right place to fix this is the Context UI module (not in core). Context UI should not be individually loading all menu items or all taxonomy terms.
Comment #38
LOBsTerr CreditAttribution: LOBsTerr commentedIn my case we have about 1000 menu items and thousands of taxonomy terms. So, context was extremely slow.
The problem was in context_reaction_menu::options_form.
I tried the patch #20, but unfortunately the part related to the context_reaction_menu class wasn't applied. But it is exactly, what helped to improve the speed of the context UI.
Thank you very much.
Comment #39
sch4lly CreditAttribution: sch4lly commentedInstead of hacking context.module like the patch in #35, you can just use hook_context_registry_alter() in a custom module to remove the taxonomy plugins:
This way you don't have to hack context and you can safely update.
Comment #40
bowersox CreditAttribution: bowersox commentedThat's a much better work-around. +1 for sch4lly
Of course the Context module should still do the more significant work of optimizing this aspect of the codebase. Large websites should not have to neuter the Context module or face 60-second+ page loads.
Comment #41
lzimmerman CreditAttribution: lzimmerman commentedUpdated to 7.x-3.2 with the hook in #39, Context UI loads just fine.
Comment #42
boshtian CreditAttribution: boshtian commentedI came to this issue, because I have lots of menus (12 languages, each with lots of nodes).
If I remove loading menu items than it works, because I don't need menu related conditions. But what if I want to add a context that has a condition or reaction based on menu. Some kind of dynamic loading should be done here. Something like Bigmenu for instance.
I will try to work something out, if anyone else comes up with a better idea, than please share it with us.
Comment #43
boshtian CreditAttribution: boshtian commentedAs I suspected, now we need condition based on menu. Because the site I'm working on is huge (13 languages with loads of content), and has lots of menu items it loads a long time. Module is running menu_link_load() for each of these items so this means the same number of queries.
Because I only needed first level of certain menus I made a little filtering before menu_link_load(). You can do this in context_condition_menu.inc in function_condition_values().
Maybe we could add some setting in the Context settings that would limit menus and level of menus loaded in the conditions.
Comment #44
Fabianx CreditAttribution: Fabianx commented#20 would just need some work, but is otherwise working nicely.
I won't have time to work on it though atm.
Comment #45
janusman CreditAttribution: janusman commentedCan confirm the patch from #20 does apply... but, my test site that has around 6k menu items:
.. and thus, it was still taking ofer 3 minutes and >500MB of RAM to generate /admin/structure/context/add (generating WSODs in the process).
Adding in this to settings.php along with the patch worked:
.. of course, that means that the Context UI doesn't offer menu options anymore.
Comment #46
vinmassaro CreditAttribution: vinmassaro commentedI applied the patch in #20 and noticed that when adding a menu condition to a context, all menus are flattened to 2 levels. Is this intended, or a bug with this patch? I didn't see any mention of it in this thread. Thanks.
Comment #47
rwohlebI've created a patch that lets an admin choose to use autocomplete fields instead of the default select field in the node taxonomy condition. This avoids all the taxonomy_get_tree() calls that can cause WSOD on sites with large vocabularies. The option can be found under "admin/structure/context/settings". All of the data in the backend remains compatible with the default select field, so if disabled everything still works.
On my site, it took the memory consumption of a test context edit-page from 460MB to 160MB. Obviously YMMV based on how many terms you have.
Comment #49
rwohlebI created a module that applies the fix in my patch from #47 using an alter hook. If you need the fix but don't want to mess with patches, well here you go.
https://www.drupal.org/sandbox/rwohleb/2450571
Comment #55
rwohlebIt looks like the unit tests that are failing have nothing to do with the patch in #47.
Comment #56
jongagne CreditAttribution: jongagne commentedHi rwohleb,
What version of Context are you using? I am using the current dev version (same as 3.6 in stable) and when I install your sandbox module, I am not presented with the option in "admin/structure/context/settings".
Also, could it be possible that the patches are failing because they are incompatible with the current version? When I tried out one of the patches a week ago, I had to go all the way back to 3.2 to apply it, which is ended up having to do manually instead of with git.
Thanks,
Jon
Comment #57
wfyanmnm CreditAttribution: wfyanmnm commentedWhen I disabled devel-themer module, it becomes faster
Comment #58
rwohleb@jongagne, we are currently on 7.x-3.6. Not sure why you won't have seen the new option.
Comment #59
Josh Waihi CreditAttribution: Josh Waihi at Acquia commentedReroll of #20 to work with latest version of Context.
Comment #60
nmillin CreditAttribution: nmillin commentedPatch #59 applied cleanly to 7.x-3.6 for me and helped speed up creating/editing contexts.
Comment #61
hass CreditAttribution: hass commentedComment #66
badrange CreditAttribution: badrange at Wunder commentedUnfortunately the patch doesn't apply to 7.x-3.7, so new re-roll is needed :)
Comment #67
badrange CreditAttribution: badrange at Wunder commentedI attempted to reroll this. WARNING: I have no way of testing the reroll myself. I also added an interdiff, which is huge, hopefully because there are many changes in the module, not because I made a mistake creating the interdiff.
Comment #68
badrange CreditAttribution: badrange at Wunder commentedComment #69
oranges13Confirm patch applies and doesn't appear to have any deleterious effects :)
Comment #70
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedBack to RTBC!
Comment #71
nmillin CreditAttribution: nmillin commented+1 to patch in #67. It applied cleanly to 3.7 and sped up creating/editing contexts.
Comment #72
grzesag CreditAttribution: grzesag commentedpatch #67 implemented on Drupal site upgraded from Drupal 6 to Drupal 7 as it was impossible to edit context rules. Now it works fast. thanks
Comment #73
slydevil CreditAttribution: slydevil commentedpatch #67 applied and we are seeing a noticeable speed improvement. Thank you.
Comment #74
dgtlmoon CreditAttribution: dgtlmoon commentedFWIW #1598698: Context crashes server when there are a lot of taxonomy terms kind of related
Comment #75
steinmb CreditAttribution: steinmb as a volunteer commentedComment #76
Delphine Lepers CreditAttribution: Delphine Lepers at Trasys for European Commission and European Union Institutions, Agencies and Bodies commentedpatch #67 tested and applied with success
Comment #77
hurricane66 CreditAttribution: hurricane66 commentedSuccessfully applied patch #67 to context 3.7. Speed improvement like others have reported. However, it seems like the patch mess up the menu hierarchy chosing action Menu from Reactions section in UI, both in regard to the wrapping of the menu names ("<" ">") as well as menu items hierarchy (all items on the same level, also missing the "-"prefix). Attach screendump that highlights the case.
Comment #78
verres CreditAttribution: verres commentedThis is still a problem, have a site with tens of thousands of terms in a hierarchical vocabulary...and context either crashes (timesout) or is very slow.... wish there were a way to turn off some vocabularies or all 'terms' in the configuration -- since Im not using the terms/vocabs for context.
Comment #79
steinmb CreditAttribution: steinmb as a volunteer commented@verres - You could start by testing the patch in #67 and report back if that worked.
Comment #80
hass CreditAttribution: hass commentedPer #77
Comment #81
oranges13Bunches of people, myself included, have tested this patch without the issue reported in #77.
Instead of delaying this fix further, we should take the majority rules and get this fixed once and for all.
Comment #82
hass CreditAttribution: hass commentedCan prove the reported issue does not exists? If this patch introduces new issues it cannot committed.
Comment #83
oranges13Cannot replicate: https://dulck.ply.st/node#overlay=admin/structure/context/add (simplytest.me uses admin/admin as the user login)
Installed context 7.x-3.7 and this patch. Working as expected.
Comment #84
oranges13Comment #85
hass CreditAttribution: hass commentedI do not see a hierarchy menu in your screenshot.
Comment #86
hass CreditAttribution: hass commentedA no, the screenshot already shows hierary is broken. Main Menu is a sub menu of Menues.