Skip to content

FilePicker performance degradation with large folder hierarchies due to missing virtual scrolling #2312

@KlementMultiverse

Description

@KlementMultiverse

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:

  1. Only render visible items in the viewport
  2. Dynamically create/destroy DOM nodes as the user scrolls
  3. Maintain smooth 60fps scrolling even with 10,000+ items
  4. 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

  1. Add virtual scrolling wrapper to FilePicker.vue list container
  2. Update any hardcoded assumptions about item count (pagination, selection)
  3. Add test cases for scrolling with 1000+ items
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions