-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Problem
When opening the FilePicker with folders containing hundreds or thousands of items, the component renders all DOM nodes at once, causing significant performance issues:
- Noticeable lag when opening the picker
- Scrolling becomes choppy or unresponsive
- Memory consumption scales linearly with item count
- On lower-end devices or mobile, the picker becomes unusable
This is a known limitation that's prevented several Nextcloud apps from using the FilePicker dialog in scenarios with large shared folders or archive browsing.
Root Cause
The FilePicker's file list rendering in packages/dialogs/src/components/FilePicker/FilePicker.vue renders the complete item array without virtualization. Even with modern CSS and browser optimizations, rendering thousands of DOM nodes exceeds practical performance thresholds for interactive components.
Expected Behavior
The FilePicker should:
- Only render visible items in the viewport
- Dynamically create/destroy DOM nodes as the user scrolls
- Maintain smooth 60fps scrolling even with 10,000+ items
- Keep memory usage flat regardless of folder size
Solution Approach
Implement virtual scrolling (windowing) for the file list:
Option A: Lightweight — Use a library like vue-virtual-scroller (already compatible with Vue 3) or @tanstack/vue-virtual
Option B: Custom — Implement a minimal virtual scroll using:
- Calculate visible range based on scroll position and item height
- Render only items in
[startIndex, endIndex]range - Keep a spacer div with height = total items × item height
- Update range on scroll events
Recommended: Option A with @tanstack/vue-virtual (10.4KB, zero dependencies, well-maintained)
Implementation Scope
- Add virtual scrolling wrapper to
FilePicker.vuelist container - Update any hardcoded assumptions about item count (pagination, selection)
- Add test cases for scrolling with 1000+ items
- Document in CHANGELOG.md as a performance fix
Acceptance Criteria
- Picker remains responsive with 10,000 items (no jank on scroll)
- Memory footprint is constant regardless of folder size
- Keyboard navigation and selection work correctly
- No visual regressions on file/folder icons, names, or metadata
- Works on both desktop and mobile viewports
Related
This addresses the performance concerns mentioned in #1904 and would improve the experience for apps handling large shared libraries, cloud storage integrations, and archive viewers.
Contributed by Klement Gunndu