New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimizing menu item parent calculation #8863
Conversation
I have tested this item 🔴 unsuccessfully on 51de1eb
This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
@Hackwar, instead of doing this: foreach ($items as $i => $item)
{
/* Code removed for simplifying */
$item->deeper = false;
$item->shallower = false;
$item->level_diff = 0;
if (isset($items[$lastitem]))
{
$items[$lastitem]->deeper = ($item->level > $items[$lastitem]->level);
$items[$lastitem]->shallower = ($item->level < $items[$lastitem]->level);
$items[$lastitem]->level_diff = ($items[$lastitem]->level - $item->level);
}
$item->parent = (boolean) ($item->rgt > $item->lft + 1) && $menu->getItems('parent_id', (int) $item->id, true);
/* Code removed for simplifying */
}
if (isset($items[$lastitem]))
{
$items[$lastitem]->deeper = (($start?$start:1) > $items[$lastitem]->level);
$items[$lastitem]->shallower = (($start?$start:1) < $items[$lastitem]->level);
$items[$lastitem]->level_diff = ($items[$lastitem]->level - ($start?$start:1));
} Can't we do something like this?: foreach ($items as $i => $item)
{
/* Code removed for simplifying */
$item->deeper = false;
$item->shallower = false;
$item->level_diff = 0;
$item->parent = 0;
if (isset($items[$lastitem]))
{
$items[$lastitem]->deeper = ($item->level > $items[$lastitem]->level);
$items[$lastitem]->shallower = ($item->level < $items[$lastitem]->level);
$items[$lastitem]->level_diff = ($items[$lastitem]->level - $item->level);
$items[$lastitem]->parent = ($items[$lastitem]->level_diff == -1);
}
/* Code removed for simplifying */
}
if (isset($items[$lastitem]))
{
$items[$lastitem]->deeper = (($start?$start:1) > $items[$lastitem]->level);
$items[$lastitem]->shallower = (($start?$start:1) < $items[$lastitem]->level);
$items[$lastitem]->level_diff = ($items[$lastitem]->level - ($start?$start:1));
$items[$lastitem]->parent = ($items[$lastitem]->level_diff == -1);
} In other words, can't we just don't use the If we can do that we get even further performance improvements. I run a test with a menu with several levels (thank for batch processing :)) and the for cycle got from:
|
This PR has received new commits. This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
First of all, sorry for the broken code. Yes, you are right, your proposal is even better. I added your code. I'm setting the parent to false by default to have it set at all times. |
I have tested this item ✅ successfully on df6acd2 Correct me if i'm wrong but the last element can't be the parent of anything, since it's the last. This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
I have tested this PR 🔴 unsuccessfully on df6acd2. Simple test, I take default installation added 5 Menu Items:
Module with "Show Sub-menu Items" off shows on active "Item 1" a difference at the last item, in this case "Item 2". Without patch: parent = true If "Show Sub-menu Items" is on the "Item 2" parent value is correct (true). Also if "Show Sub-menu Items" is on the the complete testcase is correct. |
@EFERIS we know the last item parent value can be not ok. See my comment when i tested.
But in what that affected your test? Did the menu not appeared correctly? |
@andrepereiradasilva sure because the li-tag for the last element doesn't get the "parent" class, that could lead to a visual problem if you use this class (the only way) to mark the link as parent item. |
Ok, let's wait for @Hackwar to solve that. |
This PR has received new commits. This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
This PR has received new commits. This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
Please test this again. This should solve the previous issues. |
Hi, while testing this I think I came to a better solution. Add this to the beginning of the foreach loop before filtering the unseen items.
btw. is it normal that the joomla patch tester overrides the complete file with a incompatible version? |
I think the prior solution (before revert) works, if you add this line inside the if after the for cycle (https://github.com/Hackwar/joomla-cms/blob/df6acd259cb3062ad0ec1b1499f72aa6cea3e10e/modules/mod_menu/helper.php#-L126-L131) to set the last parent:
|
@andrepereiradasilva I tested this first, but no that will not work because we don't have the child at this point. if you can please try my solution. |
ok i will check. thanks |
@EFERIS i tried you solution and it worked. And without the How did i test:
foreach ($items as $i => $item)
{
$item->parent = false;
if (isset($items[$lastitem]) && $items[$lastitem]->id == $item->parent_id)
{
$items[$lastitem]->parent = true;
}
// code removed for brevity
} @Hackwar can you check? With @EFERIS solution i think we can get rid of |
@Hackwar any comment on the proposed improvement from @EFERIS would be good to move this PR forward if we can This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
@Hackwar Another nudge so we can move this PR forward. This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
I don't know which one is @EFERIS. So far this PR is complete the way it is. |
@Hackwar sorry I renamed the github Username Instead of trying to get the ->parent value based on the level_diff its better to set it at the beginning before we delete the information. Add the following code to the beginning of the foreach loop at Line 57, see comment from @andrepereiradasilva $item->parent = false;
if (isset($items[$lastitem]) && $items[$lastitem]->id == $item->parent_id)
{
$items[$lastitem]->parent = true;
}` |
This PR has received new commits. This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
I've added the change like you proposed @HLeithner. |
This PR has received new commits. This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
One thing, adding ", m.lft, m.rgt" to the query is no longer necessary. |
@@ -54,6 +54,12 @@ public static function getList(&$params) | |||
{ | |||
foreach ($items as $i => $item) | |||
{ | |||
$item->parent = false; | |||
if (isset($items[$lastitem]) && $items[$lastitem]->id == $item->parent_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CS: We need an empty line before the if statement.
This PR has received new commits. This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
|
I have tested this item ✅ successfully on f1aa5a6 This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
I have tested this item ✅ successfully on c4d5c8c This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
This issue has two successful tests. This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/8863. |
Remove some lines
RTC This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/8863. |
Milestone changed to 3.7 as it is now not planned to have a 3.6.4 release |
mod_menu checks for every menu item if the item is a parent of another menu item. The method to do that via $menu->getItems() is pretty expensive and can create great delays on bigger sites. The proposed code will reduce this immensely by only checking those menu items that can have a child due to lft and rgt differing by more than one. Unfortunately that will not automatically mean that a menu item actually has children, since children could be present, but unpublished or in a different language. In those cases lft and rgt differ, but there is no child item anyway.
This will not change existing sites, but will mean a performance improvement. So the best way to test this would be to compare execution times on sites with a lot of menu items (>500). Another way would be a code review by a maintainer. 😄
This came up because of the insistence of @volandku in the Joomla IRC channel on Freenode who made me look into this. Thank you for being persistent. 😄