使用 Fetch API,我能够为大量二进制数据资产(比如超过 500 MB)发出网络请求,然后将其转换Response
为 aBlob
或ArrayBuffer
.
之后,我可以worker.postMessage
让标准结构化克隆算法将其复制Blob
到 Web Worker 或将其ArrayBuffer
转移到工作器上下文(使主线程不再有效)。
起初,似乎将数据作为ArrayBuffer
a获取会更可取,因为 aBlob
不可传输,因此需要复制。但是,blob 是不可变的,因此,浏览器似乎没有将其存储在与页面关联的 JS 堆中,而是存储在专用的 blob 存储空间中,因此,最终被复制到工作线程上下文的内容只是一个参考。
我准备了一个演示来尝试两种方法之间的区别:https : //blobvsab.vercel.app/。我正在使用这两种方法获取价值 656 MB 的二进制数据。
我在本地测试中观察到的一些有趣的事情是,复制 Blob 甚至比传输 更快ArrayBuffer
:
Blob
从主线程到工作线程的复制时间:1.828125 毫秒
ArrayBuffer
从主线程到工作线程的传输时间:3.393310546875 毫秒
这是一个强有力的指标,表明处理 Blob 实际上非常便宜。由于它们是不可变的,浏览器似乎足够聪明,可以将它们视为引用,而不是将覆盖的二进制数据链接到这些引用。
以下是我在作为 a 获取时拍摄的堆内存快照Blob
:
前两个快照是在Blob
使用postMessage
. 请注意,这些堆都不包含 656 MB。
后两个快照是在我使用 aFileReader
实际访问底层数据之后拍摄的,并且正如预期的那样,堆增长了很多。
现在,这就是直接作为一个 fetch 发生的情况ArrayBuffer
:
在这里,由于二进制数据只是通过工作线程传输,主线程的堆很小,但工作堆包含全部 656 …
我的应用因其上传到iCloud的内容大小而被拒绝.我的应用程序的Documents文件夹中唯一的文件是default.realm数据库文件.我认为这是iCloud上传的文件.如何阻止iCloud将数据库上传到iCloud?
谢谢.