Problem/Motivation
When executing a bulk operation on a view with exposed filters, the confirmation form (and action processing) loads and processes all entities matching the base view query and not just the filtered subset visible to the user. This causes extremely long response times on views with large result sets.
The root cause appears to be that ViewsBulkOperationsActionProcessor::populateQueue() is removing the exposed filters. It re-executes the view without applying the active exposed filter values, effectively iterating over the entire unfiltered dataset.
Steps to reproduce
- Create a view with a large number of results (e.g. 10,000+ entities).
- Add exposed filters that significantly reduce the visible result set (e.g. to ~50 items).
- Add a VBO field with a custom or core action that uses a confirmation step.
- Apply the exposed filters so only a small subset is displayed.
- Select one or more items and execute the action.
- Observe that the confirmation form takes an unreasonably long time to load - response times scale with the total unfiltered result count, not the filtered subset.
Actual behavior: The confirmation form iterates over all entities in the unfiltered view (thousands), causing long response time.
Expected behavior: Only the entities matching the currently active exposed filters should be processed. Response should be quite quick.
Workaround: Replacing exposed filters with non-exposed (contextual or hardcoded) filters resolves the performance issue, as the base query itself then only returns the relevant subset. This is not a viable long-term solution for views that require user-facing filter controls.
Possibly related issues:
- #3591877: Out of memory when building confirmation form -> likely the same root cause manifesting as OOM instead of long response times.
- #3530311: Add additional sort by langcode in
getPageList()-> different issue (translation handling), but touches the same code path inViewsBulkOperationsActionProcessor.
Some further notes
In populateQueue() there is this comment to describe why the exposed filters are ignored:
Remove all exposed filters so we don't have any default filter values that could make the actual selection out of range.
Not sure, but the function seems only be used to display the labels of selected items.
Proposed resolution
tbd
Remaining tasks
- Confirm the exact location where exposed filter values are lost during the confirmation form build.
- Implement a fix that persists and re-applies exposed filter input in the action processor.
- Add test coverage for bulk operations on views with active exposed filters.
- Verify fix against large datasets (10k+ entities) to confirm performance improvement.
User interface changes
None expected. The confirmation form should behave identically from the user's perspective. It will simply load faster and process only the correct subset of entities.
API changes
None expected.
Data model changes
None expected.
Issue fork views_bulk_operations-3615520
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
pminfComment #3
lykyd commentedI arrived on this issue after noticing that my bulk operations had a massive performance loss since I moved from Drupal 10 to 11 (but the reason was the update of VBO I had to perform alongside). I'm not sure if it should a separate issue referencing this one.
By making this fix : https://www.drupal.org/project/views_bulk_operations/issues/3591877, we ignored the fact that the count query doesn't retrieve a limited number of items based on the condition.
So the display of the confirmation form generates a query on possibly thousands on items, instead of the real number of selected items to apply the operation to.
Also, it might impact the value of `total_results` of VBO.
In my tests, setting the `count_query` seems to be fixing this behaviour but I could not dive deep into it for now :
Comment #6
graber commentedComment #8
graber commented