I am experiencing performance issues with Joomla permissions on version 5.1.1. I created a group intended to have backend access, specifically to create or edit content. While everything works fine in general, accessing Content >> Articles is extremely slow and often times out or crashes the page. This issue arises when attempting to list articles. However, this problem does not occur when you log in as a Super User.
Create a new user group with permissions to create or edit content.
Log in as a user from this group.
Navigate to Content >> Articles.
The articles list should load efficiently without significant delay or timeouts.
The page loads extremely slowly, often timing out and crashing.
Using the Joomla debugging tool, we discovered that:
For non-Super Users, Joomla checks the asset table permissions for each article individually.
This behavior does not occur with Super Users.
The attached screenshot shows a profile trace comparison:
Left: Profile trace of a Super User.
Right: Profile trace of a user with set permissions.
Can you confirm if this is a bug or native Joomla behavior?
Joomla Version: 5.1.1
Number of Articles: ~9000
The issue seems to be tied to how Joomla processes permissions for non-Super Users, causing a performance bottleneck when listing a large number of articles. Any insights or workarounds to alleviate this issue would be greatly appreciated.
Labels |
Added:
No Code Attached Yet
|
Labels |
Added:
bug
|
Any insights or workarounds to alleviate this issue would be greatly appreciated.
You can try hack the
joomla-cms/libraries/src/Access/Access.php
Line 155 in 2d99f3b
$preload
to $preload = false
However it is illegal. And I told you nothing, someone hacked my account. This message will self destroyed in few days
I tried changing $preload to $preload = false in joomla-cms/libraries/src/Access/Access.php at line 155, but the issue still persists.
Okay, I think now instead one large DB query you got a few hundrets of small DB queries. That is why it is still slow.
Another thing to try is to plreload only needed items, that in the current view.
Try, edit the articles list layout administrator/components/com_content/tmpl/articles/default.php
And place following code for preload, somewhere around line 70 (before the html rendering):
$accessWorkAround = new class () extends \Joomla\CMS\Access\Access
{
// Preload only needed items
public static function verySmartPreload($assetType, $assetsList, $key = 'id')
{
$extensionName = self::getExtensionNameFromAsset($assetType);
/** @var \Joomla\Database\Mysql\MysqlDriver $db */
$db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class);
/** @var \Joomla\Database\Mysql\MysqlQuery $query */
$query = $db->getQuery(true);
$query->select($db->quoteName(['id', 'name', 'rules', 'parent_id']))
->from($db->quoteName('#__assets'))
->where(
$db->quoteName($key) . ' IN ('
. implode(',', $query->bindArray($assetsList, \Joomla\Database\ParameterType::STRING)) . ')'
);
$assets = $db->setQuery($query)->loadObjectList();
foreach ($assets as $asset) {
self::$assetPermissionsParentIdMapping[$extensionName][$asset->id] = $asset;
self::$preloadedAssets[$asset->id] = $asset->name;
}
// Temporary mark as preloaded
self::$preloadedAssetTypes[$assetType] = true;
}
public static function resetVerySmartPreload($assetType)
{
unset(self::$preloadedAssetTypes[$assetType]);
}
};
$assetsList = [];
foreach ($this->items as $item) {
$assetsList[] = 'com_content.article.' . $item->id;
if (!empty($item->catid)) {
$assetsList[] = 'com_content.category.' . $item->catid;
}
}
$accessWorkAround::verySmartPreload('com_content.article', $assetsList, 'name');
then at the end of the file:
<?php $accessWorkAround::resetVerySmartPreload('com_content.article'); ?>
And please tell us if it help.
The editing form still will be slow, however the list view should be much faster.
After some testing, I think the actual slowdown is somewhere in ArticlesModel::getListQuery()
in the Administrator model
joomla-cms/administrator/components/com_content/src/Model/ArticlesModel.php
Lines 232 to 266 in 50726be
it takes a few seconds to load 20 articles from 40k on my test.
If I remove workflow Joins, it still more than a second.
Interestingly ArticlesModel::getListQuery()
in the Site model works much faster.
@richard67 do you have an idea what can be a bottleneck in this query?
Access preloading still preloads a lot, but it is doing it fast.
It sems a few things:
When I removing them, everything works much faster.
@richard67 do you have an idea what can be a bottleneck in this query?
@Fedik No idea. Is already the part which you have linked (lines 232 to 266) so slow, without all that stuff which might be added later below? What I remember from some other issue is that it could be faster when changing the 3 inner joins to the workflow tables to left joins:
joomla-cms/administrator/components/com_content/src/Model/ArticlesModel.php
Lines 264 to 266 in 50726be
Yea, with LEFT it 0.5s faster, but still slow in total 😄
Hmhm
it probably would be much smarter to split it to few queries:
load Articles,
load language data
load User data
load workflow data
Okay, maybe not that easy.
Kill workflow, problem solved :)
Kill workflow, problem solved
It is not only workflow
but it makes no sense to query workflow tables when its not being used.
Status | New | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2024-09-14 10:03:48 |
Closed_By | ⇒ | Fedik |
Labels |
Added:
Performance
Removed: bug |
This happens because
Access::preloadPermissions()
preloads permissions for ALL 9000 articles(which is around 90MB from your screenshot)
joomla-cms/libraries/src/Access/Access.php
Line 269 in 2d99f3b
I set it as bug, however I have no idea how it can be fixed.
But I can understand that it gives a really bad experience of use the content editing.
It probably for all Joomla versions. Cannot find older similar issue about it.