Skip to content

Viewer freezes the whole browser tab when opening a photo from a folder with thousands of images #3217

Description

@Kuvwert

Describe the bug
Opening a photo in the viewer from a folder with a lot of images (mine has around 8000) freezes the whole browser tab for about 20 seconds. The image actually shows up first and looks fine, then everything locks and Firefox pops the "a web page is slowing down your browser" warning. It comes back if I wait it out, but its rough. Folders with only a few files open instantly, so it definitly scales with the file count.

To Reproduce
Steps to reproduce the behavior:

  1. Put a few thousand images in one folder (mine is ~8000)
  2. Open that folder in the Files app (the grid loads fine and scrolls fine)
  3. Click any image to open it in the viewer
  4. Image opens, then the tab freezes ~20s and the slow script warning shows up

Expected behavior
The image opens and I can move through prev/next normally without the tab freezing, the same way it works in a normal sized folder.

Screenshots
Nothing useful, its just the standard Firefox "page is slowing down" dialog. I do have a performance profile though, see below.

Desktop (please complete the following information):

  • OS: Windows 11
  • Browser: Firefox
  • Version: 151

Smartphone (please complete the following information):

  • n/a, didnt test on mobile

Browser log

No real errors in the console, its a silent freeze and not a thrown exception. So instead of a log I grabbed a profile.

Since theres no error log, heres what the Firefox profiler showed, which is the useful part.

The freeze is entirely javascript on the main thread, about 21 seconds of it in one solid block. Stuff I ruled out: not the network (previews lazy load normally, no flood of requests), not the image (its a 420kb jpeg), and not rendering (no paint work in the hot path, it hangs before the carousel even draw).

The hot stack lands in openFileInfo in src/views/Viewer.vue, around line 803 (its 794 on 33.x), where it builds this.fileList. It runs an Array .find() over the whole folder list, inside a .map() over that same list, so the work grows with the square of the number of files. The value it compares against (node.path) also looks like it parses a URL every time its read, because almost all the self time in the profile is URL parsing and encoding (SetSpecWithEncoding, CoalescePath, encodeURIComponent and friends). At 8000 files thats a huge number of url parses, which fits why a small folder is instant and this one isnt.

Happy to attach the raw profile if you want it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    0. Needs triagePending approval or rejection. This issue is pending approval.bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions