Problem/Motivation

The usage list page loaded every source entity referencing the viewed entity, even entities not shown on the current page. For entities with many references, this loaded and processed data that pagination then discarded.

Proposed resolution

Old pipeline

ListUsageController::getRows() called listSources(), loaded every source entity with loadMultiple(), and built a row for each one. Pagination sliced the finished list afterwards.

New pipeline

  • getDisplayableEntries() calls listSources() without loading entities.
  • filterDisplayableEntries() checks entity existence and, for inline blocks, the "reusable" field, with entity queries instead of full loads. This gives the exact ordered row list and pager total.
  • listUsagePage() slices this list to the requested page. buildRows() loads only that page's source entities with loadMultiple(), grouped by type, and builds the rows.

Trade-offs

The existence and field checks have moved to filterDisplayableEntries() instead buildRows() (orphaned usage records, soft-deleted inline blocks). This opens a tiny gap where things can change while building the usage records. Given that this will only result in displaying a row that would have been just a moment before this feels acceptable.

Remaining tasks

User interface changes

API changes

Data model changes

Command icon 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

alexpott created an issue. See original summary.

alexpott’s picture

Issue summary: View changes

I've improved the issue summary with the help of an LLM.

marcoscano’s picture

👍 this approach sounds good to me.

It would just be nice to double-check we have test coverage for the use-case of paragraphs in the chain (ie usages in DB but that need to be discarded when displaying parents on the UI) as well as a pager. I don't remember if we account for that in the existing test.

Thanks for working on this!

alexpott’s picture

Status: Active » Needs review

@marcoscano paragraphs on entity_usage 5.x are no longer an issue - we don't record usages against them anymore - they're transparent :)

marcoscano’s picture

Status: Needs review » Reviewed & tested by the community

True! I'm still in a 2.x mindset... 🤦‍♂️
Thanks!

alexpott’s picture

Issue summary: View changes
alexpott’s picture

AS well can see this approach is massively more performant when dealing with an entity used thousands of times. I installed standard, enabled media, create 1 media image and added it to a node. I then cloned this node 10000 times and went to look at the media image's usage. See the stats:

5.x

Date Request / Command Custom metadata Wall time Memory Metrics Recorded calls
2026-07-23 13:37:27 GET /admin/content/entity-usage/media/1 null 1.46s 257.12MB wt, zm 4.53M
2026-07-23 13:38:05 GET /admin/content/entity-usage/media/1 null 1.45s 257.29MB wt, zm 4.56M

MR

Date Request / Command Custom metadata Wall time Memory Metrics Recorded calls
2026-07-23 13:37:46 GET /admin/content/entity-usage/media/1 null 422.79ms 11.88MB wt, zm 313.78K
2026-07-23 13:38:25 GET /admin/content/entity-usage/media/1 null 238.48ms 13.56MB wt, zm 313.65K
alexpott’s picture

And for completeness sake here is the data for a media item with a single usage. So no real performance regression for the extremely simple use-case either.

5.x

Date Request / Command Custom metadata Wall time Memory Metrics Recorded calls
2026-07-23 13:48:23 GET /admin/content/entity-usage/media/2 null 155.44ms 11.15MB wt, zm 123.75K
2026-07-23 13:48:09 GET /admin/content/entity-usage/media/2 null 130.59ms 11.47MB wt, zm 125.05K

MR

Date Request / Command Custom metadata Wall time Memory Metrics Recorded calls
2026-07-23 13:47:52 GET /admin/content/entity-usage/media/2 null 134.75ms 11.16MB wt, zm 124.31K
2026-07-23 13:47:43 GET /admin/content/entity-usage/media/2 null 153.72ms 11.57MB wt, zm 127.67K

  • alexpott committed faa175e1 on 5.x
    task: #3612704 Improve the ListUsageController to not process all the...
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.