Skip to content

Load the folder-access editor lazily to fix multi-minute freeze on large libraries#116

Open
janpospis wants to merge 2 commits into
error311:masterfrom
janpospis:fix/lazy-acl-folder-loading
Open

Load the folder-access editor lazily to fix multi-minute freeze on large libraries#116
janpospis wants to merge 2 commits into
error311:masterfrom
janpospis:fix/lazy-acl-folder-loading

Conversation

@janpospis

@janpospis janpospis commented Jul 22, 2026

Copy link
Copy Markdown

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 (via FolderModel::getFolderList()getSubfolders()) does a full recursive walk of the whole tree when no folder= is given — O(n) over the entire library. Several callers hit this:

  • the folder-access ACL editor (loaded every folder up front and rendered one row per folder),
  • AclAdminController::getUserGrants() — calls it with no arguments once per user, so it dominates the matrix load,
  • the file browser's startup/move-target folder list, portals, etc.

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 explicit folder= 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 explicit folder=) is unaffected.
  • AclAdminController::getUserGrants — read grants directly from folder_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 shallow folder=<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

  • Callers that previously enumerated the whole tree into a flat list (e.g. the "move to folder" picker) now show the top level; they can request the full list with &deep=1 where needed. On large libraries the full flat list was effectively unusable anyway.
  • No new dependencies or schema/config changes. New i18n key 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.

janpospis and others added 2 commits July 22, 2026 22:07
…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>
@janpospis
janpospis force-pushed the fix/lazy-acl-folder-loading branch 2 times, most recently from 59eb54a to 515ff52 Compare July 22, 2026 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant