javascripthtmlreactjsfile-uploadstreams-api

How do I overcome browser lag because of large file upload with AJAX (axios)?


I've implemented a simple multiple file upload function with ReactJS in the frontend using axios for AJAX requests.

const FileUploader = () => {

  const uploadFiles = files => {

    const formData = new FormData();
    files.forEach( file => {
      formData.append("files", file );
    })

    axios
    ({
      method: "POST",
      url: '...',
      data: formData,
      headers: { "Content-Type": "multipart/form-data", },
      onUploadProgress: e => console.log(e.loaded, e.total)
    })
    .then(( response ) => console.log( response ))
    .catch(( error )   => console.error( error ))
  }

  return (
   
    <input type="file" onChange={ e => uploadFiles( e.target.files ) } />

  )
}

I've noticed that while uploading large or many files at a time, not just the browser but my OS seems to lag.

Looking for a workaround, I learned the need to use Streams API to tackle this problem by sending files over the network chunk by chunk and not whole at a time.

https://developer.mozilla.org/en-US/docs/Web/API/Streams_API

The Streams API allows JavaScript to programmatically access streams of data received over the network and process them as desired by the developer.

https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams

https://developer.mozilla.org/en-US/docs/Web/API/WritableStream

However, I see very few resources on the internet on this topic probably because Streams API is a relatively new introduction to the web and is still experimental.

There are lots of articles out there explaining the implementation in the backend but very few on the frontend.

Where do I begin? What might the code look like?


Solution

  • Notice that Streams are aimed at reading/processing the file on the client and not for uploading.

    With Streams being available to JavaScript, this all changes — you can now start processing raw data with JavaScript bit by bit as soon as it is available on the client-side, without needing to generate a buffer, string, or blob.

    However, you can achieve chunked uploads using XHR. There are several libraries that support it.

    For React, there's react-uploady. Check out its chunked upload support. It also supports resumable uploads (Tus) for servers that also implement the protocol