title: JavaScript FileReader Slice Performance
body: <p>I am trying to access the first few lines of text files using the <code>FileApi</code> in JavaScript.</p>
  <p>In order to do so, I slice an arbitrary number of bytes from the beginning of the file and hand the blob over to the <code>FileReader</code>.</p>
  <p>For large files this takes very long, even though, my understanding currently is that only the first few bytes of the file need to be accessed.</p>
  <ul>
  <li>Is there some implementation in the background that requires the whole file to be accessed before it can be sliced?</li>
  <li>Does it depend on the browser implementation of the FileApi?</li>
  </ul>
  <p>I currently have tested in both Chrome and Edge (chromium).</p>
  <p>Analysis in Chrome using the performance dev tools shows a lot of idle time before the <code>reader.onloadend</code> and no increase in ram usage. This might be however, because the <code>FileApi</code> is implemented in the Browser itself and does not reflect in the JavaScript performance statistics.</p>
  <p>My implementation of the FileReader looks something like this:</p>
  <pre class="lang-js prettyprint-override"><code>const reader = new FileReader();
  
  reader.onloadend = (evt) =&gt; {
    if (evt.target.readyState == FileReader.DONE) {
      console.log(evt.target.result.toString());
    }
  };
  
  // Slice first 10240 bytes of the file
  var blob = files.item(0).slice(0, 1024 * 10);
  
  // Start reading the sliced blob
  reader.readAsBinaryString(blob);
  </code></pre>
  <p>This works fine but as described <strong>performs quite underwhelmingly for large files</strong>. I tried it for 10kb, 100mb and 6gb. The time until the first 10kb are logged seems to correlate directly to the file size.</p>
  <p><strong>Any suggestions on how to improve performance for reading the beginning of a file?</strong></p>
  <hr />
  <p>Edit:
  Using Response and DOM streams as suggested by @BenjaminGruenbaum does sadly not improve the read performance.</p>
  <pre class="lang-js prettyprint-override"><code>var dest = newWritableStream({​​​​​​​​
      write(str) {​​​​​​​​
          console.log(str);
      }​​​​​​​​,
  }​​​​​​​​);
  var blob = files.item(0).slice(0, 1024 * 10);
  
  (blob.stream ? blob.stream() : newResponse(blob).body)
  // Decode the binary-encoded response to string
    .pipeThrough(newTextDecoderStream())
    .pipeTo(dest)
    .then(() =&gt; {​​​​​​​​
        console.log('done');
    }​​​​​​​​);
  
  </code></pre>