2

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上传。


geeeger
459 声望35 粉丝

我是一个智障,你害怕了吗?我的破文章如果对您有用的话,请赏一个,感谢


引用和评论

0 条评论