Problem/Motivation
I’ve identified a significant performance issue when accessing the Extend page (/admin/modules
) on a production site with approximately 300 installed modules, including the Workflow module.
System details:
- Drupal version: 10.5
- PHP version: 8.2
- Database: MySQL 8.0
- Workflow module version: 2.1.6
Workflow statistics:
- Total workflows created: 8
- Total states: 50
- Total transitions: 442
When accessing the /admin/modules
page, the Time To First Byte (TTFB) is approximately 50 seconds.
After some investigation, I discovered that by commenting out the permission_callbacks
directive in the workflow.permissions.yml
file, clearing the cache, and reloading the page, the TTFB drops to about 6 seconds.
Digging deeper, I found that Drupal\workflow\WorkflowPermissions::getPermissions()
is being executed as many times as there are installed modules — as far as I can tell, this is expected core behavior.
However, the real performance bottleneck seems to come from the Drupal\workflow\Entity\Workflow::postLoad()
method, which loads all states and transitions for each workflow entity.
/**
* {@inheritdoc}
*/
public static function postLoad(EntityStorageInterface $storage, array &$entities) {
/** @var \Drupal\workflow\Entity\WorkflowInterface $workflow */
foreach ($entities as &$workflow) {
// Better performance, together with Annotation static_cache = TRUE.
// Load the states, and set the creation state.
$workflow->getStates(); // <--- Load all related States
$workflow->getTransitions(); // <--- Load all related Transitions
}
}
That said, it seems that in Drupal\workflow\Entity\WorkflowPermissions::buildPermissions()
, there is no need to load the full state and transition data in order to generate the permission list.
Would it be possible to load only the necessary workflow information (such as ID and label), without loading the complete state and transition entities, which are not needed in this context?
What would be the best way to optimize this process?