Performance: Coalesce concurrent tree data requests (Management API client) - #23021
Conversation
The tree data request manager hit the network on every call, so multiple concurrent consumers (sidebar tree, breadcrumb structure, pickers) each fetched the same data independently — e.g. three identical tree/document/root requests per document-workspace load. Apply the existing UmbManagementApiInFlightRequestCache (already used by the item and detail request managers) to the tree request manager via a shared static cache, coalescing concurrent identical root/children/ancestors/siblings calls into a single in-flight request, cleared on settle (in-flight only, so no stale-cache risk). The document tree opts in; other trees are unchanged until they pass a cache. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Claude finished @iOvergaard's task in 3m 45s —— View job PR ReviewTarget: Applies the existing
Important
Suggestions
Approved with Suggestions for improvementGood to go, but please carefully consider the importance of the suggestions. Labels applied: |
There was a problem hiding this comment.
Pull request overview
This PR reduces duplicate concurrent backoffice tree-data calls by introducing in-flight request coalescing in UmbManagementApiTreeDataRequestManager, and wiring it up for the document tree so multiple consumers share the same in-flight Management API request.
Changes:
- Added optional
inflightRequestCachesupport toUmbManagementApiTreeDataRequestManagerand implemented a#coalesce()helper to deduplicate identical concurrentroot/children/ancestors/siblingsrequests. - Wired the document tree request manager to use a shared static
UmbManagementApiInFlightRequestCacheto coalesce concurrent document tree requests.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
src/Umbraco.Web.UI.Client/src/packages/management-api/tree/tree-data.request-manager.ts |
Adds in-flight coalescing logic and optional cache wiring for tree requests. |
src/Umbraco.Web.UI.Client/src/packages/documents/documents/tree/server-data-source/document-tree.server.request-manager.ts |
Provides a shared static in-flight cache instance for document tree requests. |
- Add focused tests: concurrent identical root requests share one call, the in-flight entry is cleared on settle, and no cache means no coalescing. - Build the cache key lazily (only when a cache is wired) so non-opted-in trees keep the original lightweight path. - Constrain the #coalesce generic to drop the cast on cache.set. - Document the new inflightRequestCache arg; trim the comment to one line. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the review — all addressed in f146412:
Also fixed an |
AndyButland
left a comment
There was a problem hiding this comment.
This looks to work as expected. With a hard reload on a page for a document in the backoffice I see the request for /umbraco/management/api/v1/tree/document/root?skip=0&take=0 only fired once. From v17/dev it's fired twice (though not three times as stated in the PR description - there is a third call, but it has a different take value, and that's correctly retained as a separate request with this PR).
Will leave to you to merge or reach out for a more FE expert review if you feel you need one (but given it's following existing patterns, seems reasonable to proceed with to me).
|
@AndyButland, yeah, different take values will cause that for you. Perhaps we could optimise the request manager to be more intelligent to understand "skip" and "take" and collate them if the range is within the bounds of an already fired request. |
What
The backoffice tree data request manager (
UmbManagementApiTreeDataRequestManager) hit the network on every call, with no in-flight dedup. So multiple concurrent consumers of the same tree — the sidebar tree, the breadcrumb/menu-structure context, pickers — each fired their own request. A document-workspace load firestree/document/rootthree times, plus duplicate children/ancestors fetches.This applies the existing
UmbManagementApiInFlightRequestCache— already used by theitemanddetailrequest managers (webhook, language, user, templating, data-type, …) via astatic #inflightRequestCache— to the tree request manager. Concurrent identicalroot/children/ancestors/siblingsrequests now share a single in-flight call.Why
On localhost the duplicates are ~14 ms each (invisible); on high-latency hosts (e.g. Cloud) each is a full ~150 ms round-trip on the document-load critical path. This is the same dedup the item/detail managers already get — the tree manager was simply the one place the pattern was never applied.
Design
finally), so it coalesces concurrent requests and never serves stale data. No cache invalidation concerns.requestTreeRootItemsetc.inflightRequestCache; only the document tree wires the sharedstaticcache in this PR. Other trees (media, members, data-types…) are unchanged until they pass one — a natural, low-risk follow-up.How to test
tree/document/rootshould fire once instead of three times.Notes / follow-ups
getRootItems→ one underlying call). Happy to add if wanted.Related to #21152
🤖 Generated with Claude Code