STW SENTINEL LAB

双轨对比实验室 — 主线程 vs AudioWorklet 线程隔离验证

crossOriginIsolated: false
Worklet Δ
0.00 ms
主线程 Δ
0.0 ms
主线程峰值
0.0 ms
STW 次数
0
上次 STW
--
状态
IDLE
双轨实时波形对比
■ Worklet■ 主线程- - STW
绿线 (Worklet) 由 OS 音频驱动,约 2.67ms/帧,不受主线程影响。黄线 (主线程) 正常 16.6ms (60fps),STW 时飙到数百毫秒。 点「启动探针」开始监测,再点「超新星」看主线程炸裂而 Worklet 纹丝不动。

⚠ SharedArrayBuffer 不可用

如果你是在知乎/掘金 App 内打开的,App 内置浏览器不支持跨域隔离。请复制链接到 Safari / Chrome 打开。

服务器已配置 COOP/COEP 响应头:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

🎯 双轨对比原理

  • 绿线 (Worklet) — AudioWorklet 线程的调度间隔,由 OS 音频子系统驱动,约 2.67ms/帧
  • 黄线 (主线程) — 主线程 requestAnimationFrame 帧间隔,正常约 16.6ms (60fps)
  • 红色虚线 — STW 阈值 10ms,超过此值说明 V8 GC 触发了 Stop-The-World

🔬 预期现象

  • 🌌 超新星:黄线瞬间飙到数百毫秒,绿线纹丝不动 — 证明线程隔离
  • 🔒 阻塞主线程:黄线消失 200ms(rAF 无法回调),绿线平稳 — 无锁架构
  • 如果绿线也出现红色尖峰,说明 V8 真正触发了 STW,连 Worklet 都被冻结了

💓 赛博心脏

主线程卡顿瞬间,Worklet 心跳依然稳定跳动

📦 5 行代码接入你的项目

npm i stw-sentinel

import { STWSentinel } from 'stw-sentinel'
const s = new STWSentinel({
  thresholdMs: 10,
  onSpike: (d) => console.log('STW!', d.deltaUs)
})
s.init()

互动模拟器

🧪 16÷4 偏移陷阱模拟器

14 ✓ 对齐81216
✓ Int32 对齐:byteOffset = 16,是 4 的倍数,安全初始化
·
·
·
·
·
·
·
·
·
·
·
·
·
·
·
0
1
2
3
4
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
✓ Header 在第 4 格结束,刚好落在 4 字节边界

🔄 无锁环形队列模拟器

蓝圈 W = Worklet 写入(固定速率,纹丝不动),绿圈 R = 主线程读取(带抖动 + 偶发 mini-GC 卡顿)。水位自然波动。点「注入 GC STW」→ R 冻结 → W 持续灌满 → overflow。

40%
W = Worklet 写入 R = 主线程读取

正常:W 固定速率(稳),R 带抖动(晃) → 水位自然波动 | STW:R 冻结 → W 继续灌 → overflow 丢帧