web worker上传探索
闲来无事,探索一下 web worker上传。
先交代一下背景:
1. 兼容到ie10,modern mobile browser
2. 需要上传二进制内容
相关api问题
Fetch api
ie不支持,如未引入fetch-ployfill,那么无法使用,并且fetch无法监听进度事件貌似(如果是分片的话,监听不监听没什么意义)
fetch api pc环境兼容性
fetch api mobile环境兼容性
XMLHttpRequest
没问题,区别在于下面这句话
workers may use XMLHttpRequest for network I/O, with the exception that the responseXML and channel attributes on XMLHttpRequest always return null.workers可以使用XMLHttpRequest接口做网络I/O操作,但是例外的是,responseXML和channel属性总是返回null(channel属性为非标准属性,可以忽略)
responseXML为空原因在于workers没有dom api
结构化数组等
可用,支持
FileReader API
safari和ie的 webworker global 没有支持实现,在移动端safari mobile, ie mobile不支持
pc兼容性
mobile兼容性
可向worker传输的数据结构和可传输对象
前情提要: 可结构化克隆的结构体及可以以地址传输的传输对象
可结构化克隆的结构体以及可传输的对象中
- ArrayBufferView
- ArrayBuffer
- Blob
- File
- FileList 对象支持。
但仅仅只是在pc上支持程度稍微好一些,在mobile平台上支持比较惨。
结构化克隆是有开销的。
pc兼容性
mobile兼容性
直接传输以上数据,使用复制算法,除了File对象开销比较小(File对象只会在读取的时候将文件二进制数据读取进内存)
使用Transferable Object由于是地址传递,开销相对较小,但是读的操作是在主线程。并且ie以及edge, mobile平台支持程度堪忧。
克服障碍
传输结构化数据和可传输对象问题
初期解决方案是在外层使用fileReader.readAsText并传输至worker,再拼装成uint8array
不能解决的问题,效率变低了,多次解析比较伤。
比如我要处理 4 * 1024 * 1024大小的数据上传
首先需要readAsText(utf-16,utf-8的话由于是变长编码,还原麻烦), 传输至worker, 在worker中2字节2字节拆开,分成高低八位,然后再拼uint8array,拿着buffer上传。
结论
如果直接传入可复制的结构体,那么pc能兼容到 ie10,mobi不支持opera safari,并且安卓大头 android brower不支持。传入arrayBuffer有开销,并且读取arrayBuffer是在主线程的操作。
如果要解决不支持向worker传输TypedArray或者ArrayBuffer的问题。就必须自己拼buffer,得不偿失。
如果直接传入File FileList对象,那么必须舍弃移动端的worker上传。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。