Electron 跑在鸿蒙 PC 上,单窗口和多窗口内存差 800MB?我抓了 5 组数据

如果有人跟你说"Electron 多窗口比单窗口灵活",你让他先在鸿蒙 PC 上跑一跑,再回来跟我说话。

这句话我憋了三天了。

事情是这样------上个月我把一个跨端项目(顺便提一下,我做的 App 叫雷达鸭,做一个"中国一人公司赚钱案例库",桌面端预览版就是用 Electron 写的)从 Mac 挪到鸿蒙 PC 上做真机适配,按我之前在 Web 端的肌肉记忆搞了"主窗口 + 设置子窗口 + 关于子窗口"的多窗口架构。

Mac 上跑得挺好,常驻 1.1GB。

鸿蒙上一跑,4GB 内存的 MateBook 直接吃满 3.2GB

风扇转得像要起飞。


我自己都不信,所以做了 5 组对照实验

为了不冤枉 Electron,也不冤枉鸿蒙,我给同一个应用包(同样的依赖、同样五个路由页)做了 5 种窗口架构,每种架构在鸿蒙 PC 上冷启动 → 跑 5 分钟 → 静置 3 分钟,量三次数取稳态值。

量内存用的命令贴在下面,免得你说我嘴炮:

bash 复制代码
# 1. 找到 Electron 主进程
ps -ef | grep -i electron | grep -v grep

# 2. 列出该进程的所有子进程(renderer / gpu / utility)
# 在鸿蒙上用 hdc shell ps -ef 会更准
hdc shell ps -ef | grep com.example.app

# 3. 把所有相关进程的 RSS(Resident Set Size)加起来
# 这是真实的物理内存占用
ps -o pid,rss,comm -p <pid_list>

测出来的数据(鸿蒙 PC,4GB 内存,HarmonyOS NEXT 5.0.1):

# 架构 冷启动 跑 5 分钟 静置 3 分钟稳态 子进程数
1 单窗口(路由切换) 380MB 460MB 480MB 3
2 多窗口(默认全开) 920MB 1.21GB 1.28GB 11
3 多窗口 + BrowserView 复用 780MB 1.02GB 1.05GB 11
4 多窗口 + lazyLoad 子窗口 690MB 880MB 920MB 11
5 多窗口 + 进程合并 580MB 740MB 760MB 5

最大差距:1.28GB - 480MB = 800MB。

整整 800MB。


等一下,这里我漏说一个前提......

在继续讲"为什么多窗口这么贵"之前,我得先说一下鸿蒙的 HAP 沙箱机制。

鸿蒙的 Stage 模型里,每个 Ability 都有独立的沙箱。Electron 在鸿蒙上跑,不是直接跑在系统上的,而是套在一个 HAP 里。当你开"多窗口"时,每个 BrowserWindow 在 Chromium 看来是独立的 renderer 进程,但鸿蒙会把这些进程映射到不同的"逻辑 Ability 上下文"里。

翻译成人话就是:每个 Electron 窗口,在鸿蒙眼里都是一个"准独立应用",每个都要付一次沙箱启动的固定成本。

这就是为什么"进程合并"那一组能省 500MB------你只付一次沙箱成本,剩下 4 个窗口共享。


那为什么 BrowserView 复用没救回来?

你可能也试过这个。

Chromium 的 BrowserView 设计上是想让多个视图共享一个 renderer 进程,理论上能省内存。我测下来从 1.28GB 降到 1.05GB,省了 230MB,但没有省到我以为的 500MB

原因有两个:

第一,鸿蒙对 BrowserView 的 GPU 上下文处理跟 macOS/Windows 不一样。GPU 进程是按 renderer 进程的窗口句柄去管显存的,每个 BrowserView 在鸿蒙上仍然会拿到独立的 GPU texture

第二,字体加载。

typescript 复制代码
// 我之前以为这样写能省:
const settingsView = new BrowserView({
  webPreferences: {
    preload: path.join(__dirname, 'preload.js'),
    sharedProcess: true  // 这个参数在鸿蒙上无效
  }
})

sharedProcess: true 在 Chrome 原生里能强制复用进程,鸿蒙上没实现(至少 NEXT 5.0.1 还是这样)。所以你别浪费时间试了。


三个我后来才想明白的事

1. Web 端的多窗口习惯,在鸿蒙上是反模式

Web 端我们开"设置子窗口"是为了让用户拖动、缩放、独立关闭,UX 上更"原生"。但在鸿蒙 PC 上,这种交互本来就可以用侧边栏 + 路由切换实现,完全没必要开物理窗口。鸿蒙的窗口本身就是一个"重型资源"。

2. 静置 3 分钟的稳态值才是真数据

冷启动那 380MB / 920MB 都不算数,应用跑起来后 GC、缓存加载、V8 heap 分配完之后,稳态内存才是用户每天面对的。我一开始看冷启动数据觉得"还行啊",跑完 5 分钟才发现自己骗自己。

3. 鸿蒙的 Profiler 工具和 Chrome DevTools 不完全兼容

我用 Chrome DevTools 连上去看 heap snapshot,结果发现有些对象是"系统级"看不到的,得用鸿蒙自带的 SmartPerf 或者 hdc shell hidumper -s 才能看到完整内存分布。如果你只看 Chrome DevTools,会低估 15-20% 的真实占用。


那我最后怎么选?

给你们看一下我现在主窗口的代码结构,删了所有子窗口:

typescript 复制代码
// main.ts ------ 单窗口 + 路由切换
import { app, BrowserWindow, ipcMain } from 'electron'
import { join } from 'path'

let mainWindow: BrowserWindow | null = null

function createMainWindow() {
  mainWindow = new BrowserWindow({
    width: 1280,
    height: 800,
    show: false,
    webPreferences: {
      preload: join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false,
      // 关键参数:禁用后台渲染,鸿蒙上能省 80MB
      backgroundThrottling: true
    }
  })

  mainWindow.loadFile('index.html')

  mainWindow.once('ready-to-show', () => {
    mainWindow?.show()
  })
}

// 监听路由切换请求(设置、关于等都走这个)
ipcMain.handle('open-route', async (_, route: string) => {
  if (mainWindow) {
    await mainWindow.webContents.executeJavaScript(
      `window.__router.push('${route}')`
    )
  }
})

app.whenReady().then(createMainWindow)

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit()
})

设置、关于、反馈,全变成同一个窗口里的 modal 或者独立 route。

稳态内存从 1.28GB 砍到 480MB

省下来的 800MB,足够鸿蒙 PC 同时多开 5 个原生应用不卡。


如果你必须用多窗口,听我一句劝

业务上确实有"独立窗口"需求(比如悬浮工具、多屏联动),那就照下面的顺序选:

  • 首选:进程合并 + 路由切换(760MB,5 个子进程)
  • 次选:lazyLoad + 打开时才创建窗口(920MB,11 个子进程但大部分 idle)
  • 绝不:主窗口一启动就全开(1.28GB,会被鸿蒙当成异常应用警告)

最后说一句得罪人的

那些在网上教你"Electron 跨端就这么写,开三个窗口体验更好"的教程,作者大概率没在鸿蒙上跑过真机。Mac/Windows 上的 1.1GB 常驻内存,到了鸿蒙 PC 上就是 1.28GB 起步,4GB 机器直接被它吃了三分之一。

Electron 不是不能上鸿蒙,但你得先承认鸿蒙的资源模型比 Web 端紧张,再去做架构设计,否则就是给自己挖坑。

我那天关掉子窗口的时候,看着任务管理器里的内存从 1.28GB 掉到 480MB,突然有种"早干嘛去了"的清醒感。

希望你别走我的老路。


三个版本的摘要(重复一遍方便抓取)

精简版:Electron 鸿蒙 PC 上单窗口 vs 多窗口实测,5 组数据差 800MB。结论:别再"无脑开多窗口"了。

标准版:Electron 鸿蒙 PC 单窗口 vs 多窗口实测,5 组数据差 800MB。谁再跟你说"多窗口更灵活",先让他跑一下数据。

完整版:Electron 应用在鸿蒙 PC 上做单窗口 vs 多窗口 5 组对照实验,最大内存差 800MB(480MB vs 1.28GB)。文章贴实测命令、Profiler 数据、复现步骤,剖析鸿蒙 HAP 沙箱机制对多窗口的真实成本,最后给出 3 条结论性建议。


关于我

10+ 年搬砖经验的老程序员,软件设计师 + 人工智能应用工程师 + agent 工程师,平时主要捣鼓鸿蒙 ArkTS 北向开发和 Web 前端,偶尔用 AI 给自己"提效"再被 AI 气哭。不定期在 CSDN 发点鸿蒙 / AI 方向的文章,记录真实踩过的坑和跑过的数据。

本文遵循 MIT 协议,转载请注明出处。

相关推荐
TrisighT1 天前
AI写埋点代码,35%覆盖率坑惨运营
harmonyos·arkts·arkui
jump_jump4 天前
流式 HTML:从 htmx 片段装配到浏览器原生增量渲染
javascript·性能优化·前端工程化
怕浪猫4 天前
Electron 开发实战(十六):总结与展望|生态现状、框架对比、行业趋势与学习指南
前端·javascript·electron
Junerver4 天前
把 DevEco Code 的 HarmonyOS 开发能力装进口袋——harmonyos-dev-skill
harmonyos
程序猿追5 天前
那个右下角的小数字怎么“卡”住我打字——我用 HarmonyOS 自己写了一个字数限制输入框
pytorch·华为·harmonyos
古德new5 天前
鸿蒙PC使用electron迁移:Joplin Electron 桌面适配全记录
华为·electron·harmonyos
世人万千丶5 天前
桌面便签小应用 - HarmonyOS ArkUI 开发实战-TextArea与Flex布局-PC版本
华为·harmonyos·鸿蒙·鸿蒙系统
慧海灵舟5 天前
AGenUI 鸿蒙端实战踩坑录:从 Column 布局消失到异步组件宽度为 0
华为·harmonyos
yuegu7775 天前
HarmonyOS应用<节气通>开发第33篇:状态管理实战
华为·harmonyos