閒來無事,探索一下 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上傳。