Load the folder-access editor lazily to fix multi-minute freeze on large libraries#116
Load the folder-access editor lazily to fix multi-minute freeze on large libraries#116janpospis wants to merge 2 commits into
Conversation
…rants The admin folder-access matrix and the folder-list endpoint pulled the entire folder tree recursively (FolderModel::getSubfolders), which is O(n) over the whole library and froze the UI for minutes on large trees. - getFolderList: default to a shallow top-level listing when no folder= is given; the full recursive list is still available via &deep=1. - getUserGrants: read grants straight from folder_acl.json (the only folders that can carry a grant) instead of walking every folder. getGrants runs once per user, so this was the dominant cost. Measured on a ~50k-folder library: getUserGrants ~239s -> ~0.006s. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The folder-access editor loaded the whole folder tree up front and rendered one row per folder, freezing on large libraries. Load one level at a time (shallow) and add a breadcrumb plus per-row drill-in to reach subfolders. In-progress edits are collected into the fallback map before navigating, so the batched save still persists grants from every visited level. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59eb54a to
515ff52
Compare
|
Thank you This addresses a real performance problem, and the ACL-file optimization plus lazy editor loading look valuable. I found a few compatibility issues that need adjustment before merge. Please preserve the existing default recursive behavior of Drill-in rendering also needs to reapply inherited group locks and read-only group-preview state, and administrator permissions should remain visibly enabled on newly loaded levels. Please add focused regression coverage for these cases and saving permissions across multiple visited levels. Once those points are addressed, I’m happy to target the change for next release.. |
Problem
On a large library, loading the folder list freezes for minutes. It is most visible in the admin Folder access editor (the user × folder permission matrix), but it also affects other places that request the full folder list (the file browser's startup default-folder detection, the "move to folder" picker, portals).
Root cause
getFolderList.php(viaFolderModel::getFolderList()→getSubfolders()) does a full recursive walk of the whole tree when nofolder=is given — O(n) over the entire library. Several callers hit this:AclAdminController::getUserGrants()— calls it with no arguments once per user, so it dominates the matrix load,On a ~50k-folder library,
getUserGrants('<user>')measured ~239 s; the walk returned 50,293 folders in 239 s vs 24 top-level folders in 0.11 s.Changes
FolderController::getFolderList— when no explicitfolder=is given, default to a shallow (top-level) listing instead of the full recursive walk. This fixes every caller that pulled the whole list at once. The full recursive list is still available via&deep=1, and directory navigation (which passes an explicitfolder=) is unaffected.AclAdminController::getUserGrants— read grants directly fromfolder_acl.json(the only folders that can carry a grant) instead of walking the tree. ~239 s → ~0.006 s.adminFolderAccess.js— the folder-access editor now loads one level at a time (using the shallowfolder=<path>mode) with a breadcrumb and per-row drill-in to reach and set permissions on subfolders. In-progress edits are collected into the existing fallback map before navigating, so the batched save still persists grants from every visited level.Notes
&deep=1where needed. On large libraries the full flat list was effectively unusable anyway.open_subfolders(falls back to "Open subfolders").Testing
Verified on a ~50k-folder local library: the folder-access editor and folder-list loading no longer freeze, drill-in reaches subfolders, and saving persists grants set across multiple levels.