Browser hangs on reading large folder on client side

Viewed 118

I am trying to create a simple folder uploader (client side). The minimum required functionality is to be able to select a folder/file(s) and show on the browser the information of all files. I have used a simple input element:

const ReadFolder = () => {
    const onFileChange = (event: React.ChangeEvent<HTMLInputElement>) => console.log(event.target.files);
    return (
        <input
          type='file'
          directory
          webkitdirectory
          multiple
          onChange={onFileChange}
        />
    );
}

The onFileChange function just shows the info of received file list.

It works fine for small folders, but when I try to upload a git repository from my computer (which has a large nested folder hierarchy), the browser window becomes unresponsive for around 2 minutes before the onChange event is reported. Is there a way I can avoid this unresponsiveness? Can I push this processing to background (or to a web worker)?

1 Answers

This processing may not even be done by the browser's process, but rather by the OS directly, which is building a list of metadata for all the files in the directory and its sub-directories. That is a lot of I/O.
You are not the first one to report such an issue with some configurations (OS or file system, it's still unclear to me) having trouble to generate files' metadata when being asked by the browser through the <input type="file">.

So moving whatever to a Worker would most probably not help at all. My educated guess would be that your HDD is the bottleneck, not the CPU.

What you can try in supporting browsers, is to request a handle over the directory rather than requesting all the files in a single call.
The new File System API has a showDirectoryPicker method which would allow you to gain access to the directory, and to read only the files you need, and if you need them all, to do this in a streaming manner, allowing your page to render part of what has already been parsed while it is being parsed.

You can see a live demo here, which will currently only work in Chrome.

Note that directories gotten from a drag&drop event should not be read entirely either, and that you should also be able to navigate them by batches, with better browser support, so if you can, try to make your UI force your users to use this method instead.

Related