Web Worker是处理传感器数据平滑的必要隔离层,需传轻量采样对象、Worker内用环形缓冲+IIR滤波、主线程按需拉取结果、可选Transferable提升吞吐。

在HTML5中用Web Worker异步处理传感器采样数据平滑,关键是把耗时的滤波计算(如滑动平均、低通、卡尔曼预估)从主线程移出,避免阻塞渲染和输入响应。iOS或Android WebView中传感器事件本就稀疏且易抖动,直接在主线程做多点缓存+插值,极易掉帧甚至卡死。Worker不是“锦上添花”,而是处理高频采样平滑的必要隔离层。
只传原始采样,不传DOM或回调
主线程采集到devicemotion或getSensor数据后,应立即提取核心字段(如x/y/z、timestamp),封装为轻量对象发送给Worker。禁止传event对象、this引用或函数——这些无法序列化,会触发postMessage静默失败。
- ✅ 正确示例:
{"ts":1746786123456,"ax":0.12,"ay":-0.87,"az":9.78} - ❌ 错误做法:传
event整个对象,或附带console.log、requestAnimationFrame回调 - 建议加一个单调递增的序号
seq字段,便于Worker端检测丢包或乱序
Worker内实现环形缓冲+实时滤波
Worker不做复杂建模,专注低开销平滑:用固定长度的环形数组(如长度5~12)缓存最近采样,每次新数据进来,就用加权移动平均或一阶IIR滤波更新输出值。所有计算纯数值,无任何API调用。
- 维护
buffer = [{ts, ax, ay, az}, ...],插入时用buffer.push(data); buffer.shift()保持长度 - IIR推荐公式:
out = out * 0.8 + current * 0.2(系数可调,0.9更稳、0.5更跟手) - 若需时间对齐(如多轴同步),用
performance.now()替代event.timeStamp,Worker中也能安全调用
主线程按需拉取,不主动轮询
Worker不主动发结果,等主线程“问”才“答”。这样能避免无效通信和资源浪费,尤其适合传感器数据变化缓慢的场景(如姿态微调、慢速位移)。
立即学习“前端免费学习笔记(深入)”;
- 主线程用
requestIdleCallback或setTimeout(..., 0)定期向Worker发{"type":"getSmoothed"} - Worker收到后,立即返回当前滤波结果
{"ax":0.118,"ay":-0.865,"az":9.782,"ts":1746786123456} - 返回结果带
ts,主线程比对上次时间戳,跳过过期数据,防止“倒退”抖动
配合Transferable提升吞吐量
若需每秒处理上百组三轴数据,可用ArrayBuffer代替普通对象传输,启用transferable选项避免内存拷贝。适用于长周期连续采样(如体感训练、VR定位)。
- 主线程构造
new ArrayBuffer(24)(3个float64),填入x/y/z和时间戳 - 调用
worker.postMessage(buf, [buf]),buf在主线程立即失效,零拷贝移交Worker - Worker用
new Float64Array(buf)读取,处理完再传回新buffer - 注意:必须确保主线程不再访问该buffer,否则行为未定义



















