闲来无事,探索一下 web worker上传。android
先交代一下背景:web
1. 兼容到ie10,modern mobile browser 2. 须要上传二进制内容
ie不支持,如未引入fetch-ployfill,那么没法使用,而且fetch没法监听进度事件貌似(若是是分片的话,监听不监听没什么意义)算法
fetch api pc环境兼容性api
fetch api mobile环境兼容性数组
没问题,区别在于下面这句话网络
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 apidom
可用,支持ide
safari和ie的 webworker global 没有支持实现,在移动端safari mobile, ie mobile不支持fetch
pc兼容性
mobile兼容性
前情提要: 可结构化克隆的结构体及能够以地址传输的传输对象
可结构化克隆的结构体以及可传输的对象中
但仅仅只是在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上传。