web worker开销统计

发布时间 2023-08-10 14:30:16作者: 汪氵淼

准备利用worker干点有用的、实际的大事。在肆意霍霍worker前,先总结统计下其开销以心安。

首先web worker的分类有下面几种:

  1. Worker,专用worker。
  2. ServiceWorker,服务worker,常用于缓存、推送消息处理。
  3. SharedWorker,多页面共享worker,常用于一系列页面间的通信,但使用要求严格需服务器端配置才可用。

关于Worker的知识可参考《JavaScript并发编程:第5章-使用Web Workers》

使用Chromium浏览器测试 Web Workers

安装指定版本的浏览器可以使用 npx @puppeteer/browers install chromium,这也是 chromium 官方推荐的安装方式之一。

打开一个带 Worker 的页面,通过 TaskManager 查看页面的进程 ID,再通过 ps -T -p 12345【页面进程ID】 可看到 专用Worker 线程的信息。

$ ps -T -p 32068
  PID  SPID TTY          TIME CMD
32068 32068 pts/10   00:00:00 chrome
32068 32070 pts/10   00:00:00 ThreadPoolServi
32068 32071 pts/10   00:00:00 ThreadPoolForeg
32068 32072 pts/10   00:00:00 ThreadPoolForeg
32068 32073 pts/10   00:00:00 Chrome_ChildIOT
32068 32074 pts/10   00:00:00 GpuMemoryThread
32068 32078 pts/10   00:00:00 Compositor
32068 32079 pts/10   00:00:00 ThreadPoolSingl
32068 32480 pts/10   00:00:00 Preload scanner
32068 32502 pts/10   00:00:00 DedicatedWorker
32068 32503 pts/10   00:00:00 DedicatedWorker
32068 32504 pts/10   00:00:00 DedicatedWorker
32068 32505 pts/10   00:00:00 DedicatedWorker

我这里测试了同时使用 4 个 Worker 并跑满,可看到其可以占据 4 个核心 100% 的使用:

不同 worker 数量的内存占用情况

0个:

1个:

2个:

4个:

8个:

对比

数量 Memory footprint JavaScript memory
0个 18192K 2124K(750K live)
1个 19868K 3852K(1480K live)
2个 20344K 5324K(1717K live)
4个 23056K 8268K(2935K live)
8个 27304K 14412K(4989K live)

随worker数量的指数增长,内存占用增长近乎 1.5 倍。

Worker 通信开销

worker通信的主要开销在: JSON 的序列化和反序列化。

因为设计原因(浏览器厂商故意而为之),页面主线程和worker线程间的通信必须通过JSON序列化和反序列化这一步,因此这个固定存在的开销将随消息条变大而线性增长。

根据经验,通信消息大小是存在最优值的,不宜太大、不宜太小,这个中间值跟随设备变化。所以想获得较优的通信效果,最好还是使用一个MQ(MessageQueue)来合并、拆分消息。

有机会在不同设备上测测以下两点:

  1. JS主线程到Worker线程
  2. Worker线程到Worker子线程