navigator.hardwareConcurrency返回设备逻辑CPU核心数(含超线程),是静态参考值而非实时并发能力,需兼容undefined并结合任务类型动态设定Worker数量。

用 navigator.hardwareConcurrency 获取 CPU 逻辑核心数
现代浏览器通过 navigator.hardwareConcurrency 暴露设备可用的逻辑处理器数量,这是最轻量、无需权限、不触发跨域限制的硬件线程数检测方式。它返回的是操作系统报告的“逻辑核心数”(含超线程),不是物理核心数,也不代表当前可用线程——只是个静态建议值。
常见错误是把它当实时负载指标或并发上限硬控依据。实际上它只在页面加载时读取一次,且部分旧版浏览器(如 Safari ≤ 15.4、IE)完全不支持,返回 undefined。
- 直接访问:
navigator.hardwareConcurrency,典型值为 2、4、8、16、32 - 兼容 fallback:若为
undefined,可退回到1或基于经验设为4(多数移动端最低保障) - 不要用于判断是否启用 Web Worker:即使值为 2,仍可创建 10 个 Worker,只是调度效率可能下降
为什么不能用 JavaScript 主动“检测”真实并发能力
JS 是单线程执行环境,无法像系统工具(lscpu、os.cpus())那样枚举或轮询 CPU 状态。所谓“检测”,本质只是读取浏览器从 OS 缓存的静态字段,不是运行时探测。
试图用密集计算 + performance.now() 估算并行度会失败:JS 主线程被阻塞时,所有定时器、微任务、甚至 setTimeout(0) 都延迟,测出来的是事件循环拥堵程度,不是 CPU 核心数。
- Web Worker 中读取
navigator.hardwareConcurrency和主线程一致,不会更高 -
performance.timeOrigin或performance.memory与核心数无直接关系 - 没有标准 API 能区分物理核 / 逻辑核,或获取当前 CPU 频率、温度、占用率
结合 Web Worker 做合理线程分配的实际写法
拿到 navigator.hardwareConcurrency 后,真正关键的是怎么用。多数场景下,你不需要“用满所有核心”,而是避免过度创建 Worker 导致内存和上下文切换开销反超收益。
例如图像批量处理、加密解密、大型数组排序等 CPU 密集型任务,推荐按比例分配:
- 默认使用
Math.min(navigator.hardwareConcurrency || 4, 4)—— 多数情况下 4 个 Worker 已足够,再往上提升极小 - 移动端谨慎:iOS Safari 对 Worker 数量有限制(通常 ≤ 4),且后台 tab 会冻结 Worker
- 创建前检查:
if (typeof Worker !== 'undefined'),否则降级为同步执行 - 示例初始化:
const workerCount = Math.min(navigator.hardwareConcurrency || 4, 4); const workers = Array.from({ length: workerCount }, () => new Worker('processor.js'));
容易被忽略的兼容性与实效边界
navigator.hardwareConcurrency 在 Chrome 61+、Firefox 60+、Edge 79+ 支持良好,但 Android WebView(尤其旧版)和部分国产浏览器内核仍返回 undefined。更隐蔽的问题是:即使值存在,它也可能被浏览器主动降级——比如在电池省电模式下,Chrome 会将该值设为 2 或 1,即使设备实际有 8 核。
所以不能假设它稳定不变,也不该在初始化后长期缓存。如果任务持续时间长(>30s),建议在关键节点重新读取,或监听 visibilitychange 后重估资源可用性。
真正的难点从来不在“怎么拿到数字”,而在于:这个数字到底该不该信、什么时候信、信了之后敢不敢真按它分配资源——这些都得靠具体任务特征和用户设备反馈来校准。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











