Skip to content

Conversation

@landlogicit
Copy link
Contributor

Summary

This PR improves the Media Picker performance when browsing folders
containing a large number of media items.

Changes

  • Replaces entityResource.getChildren with entityResource.getPagedChildren
    in MediaPickerController.
  • Adds support for orderBy/orderDirection and sets a default pageSize of 200.
  • Resets pagination when entering folders and when clearing search filters.
  • Updates changePagination to handle both folder browsing and search results.

Why

Currently the Media Picker loads all children of a folder in one call,
which can be very slow or even cause timeouts when the folder contains
hundreds or thousands of media items.
By using getPagedChildren we only load one page of results at a time,
improving performance and memory usage.

Breaking changes

None.
This is a pure client-side change; no modifications to EntityController
or server-side APIs are required. Existing external consumers of the
back-office API remain unaffected.

Testing

  1. Open the Media Picker and navigate to a folder with a large number of media items.
  2. Verify that only the configured page size (default 200) is loaded initially.
  3. Use the pagination controls to navigate to other pages and confirm
    that items are loaded and displayed correctly.
  4. Search for media and navigate pages to ensure search pagination still works.

AndyButland and others added 7 commits September 4, 2025 14:29
fix bug for Media Picker is slow when you have a large number of images at the root folder umbraco#12364
This reverts commit 4d86734.
Replaces folder view calls to entityResource.getChildren with
entityResource.getPagedChildren in MediaPickerController.

- Adds orderBy/Direction and increases default pageSize to 200
- Resets pagination when entering folders or clearing search
- Updates changePagination to work for both search and folder views
- Keeps legacy behaviour for searchMedia (no breaking server changes)
@github-actions
Copy link

Hi there @landlogicit, thank you for this contribution! 👍

While we wait for one of the Core Collaborators team to have a look at your work, we wanted to let you know about that we have a checklist for some of the things we will consider during review:

  • It's clear what problem this is solving, there's a connected issue or a description of what the changes do and how to test them
  • The automated tests all pass (see "Checks" tab on this PR)
  • The level of security for this contribution is the same or improved
  • The level of performance for this contribution is the same or improved
  • Avoids creating breaking changes; note that behavioral changes might also be perceived as breaking
  • If this is a new feature, Umbraco HQ provided guidance on the implementation beforehand
  • 💡 The contribution looks original and the contributor is presumably allowed to share it

Don't worry if you got something wrong. We like to think of a pull request as the start of a conversation, we're happy to provide guidance on improving your contribution.

If you realize that you might want to make some changes then you can do that by adding new commits to the branch you created for this work and pushing new commits. They should then automatically show up as updates to this pull request.

Thanks, from your friendly Umbraco GitHub bot 🤖 🙂

@landlogicit landlogicit mentioned this pull request Sep 19, 2025
1 task
@landlogicit
Copy link
Contributor Author

Please review this pr, Thanks

Copy link
Contributor

@AndyButland AndyButland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for this @landlogicit. I've done some testing having artificially set a low number for the page size, and it all looks to work as expected.

I left a few inline comments below if you wouldn't mind taking a look at please? Some questions as to why certain changes were necessary, and some on the various comments added that feel more like points for the code reviewer and won't be useful or could be confusing once the PR is merged.

…ments

- Removed unnecessary helper methods (pickPositive / pickNonNegative) and assign pagination values directly,
  as backend always provides valid positive/ non-negative numbers.
- Renamed or removed review-only comments to keep codebase clean.
- Clarified purpose of resetting `vm.searchOptions.filter` to explain why the filter is cleared after loading items.
- Adjusted indentation and minor formatting for consistency.
@landlogicit
Copy link
Contributor Author

Pushed an update that:

Removes the pickPositive/pickNonNegative helpers and assigns pagination values directly, since the API guarantees valid numbers.

Cleans up or removes review-only comments.

Clarifies the purpose of resetting vm.searchOptions.filter when navigating folders.

Fixes minor indentation/formatting.

This should address all review comments and keep the MediaPickerController cleaner and easier to maintain.

Copy link
Contributor

@AndyButland AndyButland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates. The code all looks good now, but I found an issue in testing. Do you think you might be able to find a solution to this please?

  • Open media picker
  • Navigate into a folder that has more items than the page size.
  • Navigate to page 2.
  • Close the media picker.
  • Open the media picker again. You will be returned to the last folder you were looking at, however now all items are shown rather than just a single page, and there's no paging details displayed.

@landlogicit
Copy link
Contributor Author

Thanks for the catch! I’ve updated the navigation flow so that run(), ensureWithinStartNode(), gotoStartNode() and gotoFolder() consistently return and chain the same promise, ensuring the paged fetch (getChildren → getPagedChildren) always runs when restoring the last folder.

This fixes the issue where reopening the media picker shows all items without paging metadata.

Ensures the Media Picker always loads a paged result when restoring the last
visited folder.

- run(), ensureWithinStartNode(), gotoStartNode(), and gotoFolder() now return
  and chain the same promise flow.
- gotoFolder() resolves path → sets current folder → resets pagination →
  calls getChildren() (which uses getPagedChildren).
- Fixed cases where reopening the picker showed all items with no pager.
- Kept existing UX: filter is cleared on folder navigation to start unfiltered.
- Minor indentation/formatting cleanups.
Copy link
Contributor

@AndyButland AndyButland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does seem to work now, but the last commit contains quite a bit more change than I'd have expected. Can I ask if you are getting some AI help here? Not against that, but I'd like to make sure you are clear why the changes you are proposing resolve the issue, and to include only changes that are necessary. I get nervous otherwise! Could you share your method here please?

@landlogicit
Copy link
Contributor Author

Thanks Andy, I completely understand your concern and I appreciate the careful review.
I did use AI as a support tool to speed up some repetitive editing (mainly to draft code and formatting), but every change was reviewed, tested and understood by me.

The essential fix is about promise chaining: run(), ensureWithinStartNode(), gotoStartNode(), and gotoFolder() now consistently return and chain the same promise so that the paged fetch (getChildren → getPagedChildren) always runs when restoring the last folder.
This is the key to solving the issue where reopening the picker showed all items without paging metadata.

I can certainly trim or squash the commit to show only those minimal, necessary changes if that helps make the diff clearer and keeps history clean.
Please rest assured I fully understand and stand by the solution.

@AndyButland
Copy link
Contributor

Fantastic, thanks very much for the explanation @landlogicit. Don't worry about the git history, that's not a concern as we'll squash the PR when merging anyway. Now you've explained the solution you've come up with that's good for me.

Copy link
Contributor

@AndyButland AndyButland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have manually tested fix by temporarily configuring a low page size, and verifying top level and lower level folders correctly handle paging.

Thanks very much for the effort on this @landlogicit, and the fix, it's much appreciated.

@AndyButland AndyButland enabled auto-merge (squash) September 26, 2025 06:18
@AndyButland AndyButland changed the title [v13] Media Picker: implement paging using getPagedChildren (no server changes) Media Picker: implement paging Sep 26, 2025
@AndyButland AndyButland changed the title Media Picker: implement paging Media Picker: Implement paging Sep 26, 2025
@AndyButland AndyButland merged commit 9ad24ac into umbraco:v13/dev Sep 26, 2025
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants