Skip to content

Instantly share code, notes, and snippets.

@myl7
Created November 5, 2021 08:44
Show Gist options
  • Save myl7/7529ca69b662a567dfa7919d6c2ef466 to your computer and use it in GitHub Desktop.
Save myl7/7529ca69b662a567dfa7919d6c2ef466 to your computer and use it in GitHub Desktop.
Experiment to decide which way is the best one to process large (such as > 1GB) binary data in JS
<input id="input" type="file" onchange="handle()" />
<script>
let a
const handle = () => {
let e = document.getElementById('input')
let f = e.files[0]
setInterval(() => {
// console.log(f)
// No mem usage increament
// At least in Chrome, Blob is automatically put on memory or disk
// Ref https://chromium.googlesource.com/chromium/src/+/refs/heads/main/storage/browser/blob/README.md
// f.arrayBuffer().then(b => {
// a = b
// console.log(a)
// })
// Huge mem usage increament
// Each arrayBuffer call will read the blob into memory respectively
// f.arrayBuffer().then(b => {
// a = new Uint8Array(b)
// console.log(a)
// })
// Huge mem usage increament
// We can predict it, as extra UInt8Array will not change anything
// a = f.stream()
// console.log(a)
// No mem usage increament
// Get ReadableStream will no cause loading into memory
// a = f.stream().getReader()
// console.log(a)
// No mem usage increament
// Get ReadableStreamDefaultReader will no cause loading into memory
// One more wired thing, on Safari ReadableStreamDefaultReader is not (ensured to be) supported according to caniuse, but getReader is supported according to MDN
// I just wonder what is the return value of getReader...
// Anyway, you can include a web-streams-pollfill package to pollfill/ponyfill it, which is really small, < 10KB
f.stream().getReader().read().then(({ value, done }) => {
console.log(value.length, done, value)
})
// No mem usage increament
// The (default) reader indeed confuses me, as the read method has no args, which will read a "chunk" according to MDN, and the user can configure nothing about it
// As for me, the len sometime is 65536 and sometime is 131072, which is pretty good for use
// getReader has a mode param, and can return a ReadableStreamBYOBReader reader (BYOB = bring your own buffer), which may fit our imagining of normal reader like other language, but it is even not supoorted by Firefox.
// All in all, when working with really large files (such as > 1GB), the best way (which has least memory footprint) may be using stream reader with pollfill
}, 1000)
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment