electron系列1:Electron不是玩具,为什么桌面应用需要它?

张开发
2026/4/18 0:58:05 15 分钟阅读

分享文章

electron系列1:Electron不是玩具,为什么桌面应用需要它?
一、一个前端工程师的困惑2018年我第一次听到Electron当时的反应和很多人一样“用网页技术写桌面应用这不就是套个浏览器壳子吗能好用吗”这个偏见在很长时间里影响了我。直到后来我发现自己每天都在用的VSCode、Slack、Figma、Notion竟然都是Electron写的。如果这些产品都在用那一定不只是“套壳”那么简单。二、Electron到底是什么官方的定义很简洁Electron是一个使用JavaScript、HTML和CSS构建跨平台桌面应用程序的框架。但这句话太抽象了。让我们用一张图来看清楚Electron的架构我更喜欢用这个公式来理解它Electron Chromium Node.js 原生API拆开来看组成部分作用通俗解释代码示例Chromium渲染界面用你熟悉的HTML/CSS/JS画界面div、button、flexboxNode.js调用系统能力读写文件、执行命令、访问数据库fs.readFile()、child_process.exec()原生API桌面集成系统托盘、全局快捷键、通知Tray、globalShortcut、NotificationElectron不是“套壳浏览器”而是让前端代码获得了接近原生应用的系统能力。三、一个最小Electron应用长什么样让我们写一个最简单的Electron应用来感受它到底做了什么项目结构my-electron-app/ ├── package.json ├── main.js # 主进程 ├── preload.js # 预加载脚本安全桥接 └── index.html # 渲染进程页面1. package.json{ name: my-electron-app, version: 1.0.0, main: main.js, scripts: { start: electron . }, devDependencies: { electron: ^28.0.0 } }2. main.js主进程const { app, BrowserWindow } require(electron) const path require(path) // 创建窗口的函数 const createWindow () { const win new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, preload.js), // 预加载脚本 contextIsolation: true, // 开启上下文隔离安全必须 nodeIntegration: false // 禁止渲染进程直接访问Node安全必须 } }) win.loadFile(index.html) // 打开开发者工具开发时使用 // win.webContents.openDevTools() } // 应用准备就绪后创建窗口 app.whenReady().then(() { createWindow() // macOS点击dock图标时如果没有窗口就创建一个 app.on(activate, () { if (BrowserWindow.getAllWindows().length 0) createWindow() }) }) // 所有窗口关闭时退出应用除了macOS app.on(window-all-closed, () { if (process.platform ! darwin) app.quit() })3. preload.js预加载脚本 - 安全桥接const { contextBridge, ipcRenderer } require(electron) // 安全地暴露API给渲染进程 contextBridge.exposeInMainWorld(electronAPI, { // 读取文件调用主进程的Node能力 readFile: (filePath) ipcRenderer.invoke(read-file, filePath), // 保存文件 saveFile: (filePath, content) ipcRenderer.invoke(save-file, filePath, content), // 获取系统信息 getSystemInfo: () ipcRenderer.invoke(get-system-info) })4. index.html渲染进程 - 这就是普通的Web页面!DOCTYPE html html head meta charsetUTF-8 title我的第一个Electron应用/title style body { font-family: system-ui, -apple-system, sans-serif; margin: 0; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; } .container { text-align: center; padding: 40px; } button { background: white; border: none; padding: 12px 24px; font-size: 16px; border-radius: 8px; cursor: pointer; margin: 10px; transition: transform 0.2s; } button:hover { transform: scale(1.05); } pre { background: rgba(0,0,0,0.3); padding: 15px; border-radius: 8px; text-align: left; overflow-x: auto; } /style /head body div classcontainer h1欢迎使用Electron/h1 p这是一个真正的桌面应用/p button idsystemBtn获取系统信息/button button idfileBtn读取文件/button div idoutput pre点击按钮结果会显示在这里.../pre /div /div script // 调用通过preload暴露的API const output document.getElementById(output) document.getElementById(systemBtn).onclick async () { // 注意这里可以直接调用桌面能力 const info await window.electronAPI.getSystemInfo() output.innerHTML pre${JSON.stringify(info, null, 2)}/pre } document.getElementById(fileBtn).onclick async () { // 这里调用的是Node.js的文件读取能力 const content await window.electronAPI.readFile(package.json) output.innerHTML pre${content}/pre } /script /body /html关键理解index.html里的代码看起来就是普通前端代码但它能调用window.electronAPI.getSystemInfo()——这是纯Web页面做不到的。四、那些你不知道的Electron产品很多人用了很久都不知道这些产品是Electron写的产品类型日活/用户量为什么选ElectronVisual Studio Code代码编辑器1500万需要Web技术生态 性能要求高Figma设计工具400万实时协作能力WebSocket 跨平台Notion笔记应用1亿用户富文本编辑器 快速迭代Slack企业通讯1200万日活与Web版本复用代码Discord游戏语音1.5亿用户低延迟通信 游戏内覆盖层1Password密码管理1500万跨平台一致性 安全性可控GitHub DesktopGit客户端数百万与GitHub生态无缝集成这些产品的共同点需要快速迭代Web技术开发效率高需要跨平台Windows/macOS/Linux一套代码对界面交互有较高要求CSS动画、Canvas渲染有Web版本代码复用率高五、Electron vs 传统方案选型决策表这是我给团队做技术选型时用的决策矩阵维度ElectronQt/CWPF/C#JavaFXTauri (Rust)开发效率⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐运行时性能⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐内存占用~80MB起步~20MB~30MB~40MB~10MB安装包大小~70MB~5MB~10MB~40MB~2MB跨平台⭐⭐⭐⭐⭐⭐⭐⭐⭐❌⭐⭐⭐⭐⭐⭐⭐⭐⭐原生体验⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐社区生态⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐学习成本⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐注Tauri是较新的替代方案使用系统WebView而非Chromium体积更小但兼容性略弱。决策流程图决策建议选Electron需要快速迭代、跨平台、有Web技术栈积累选Qt/C需要极致性能游戏引擎、CAD软件、或嵌入式设备选WPF只做Windows、有C#技术栈、需要深度系统集成选Tauri追求小体积、团队熟悉Rust、不需要老平台支持六、Electron的三大核心优势优势1Web技术栈的杠杆效应前端生态的价值Vue、React、Svelte等框架直接可用npm上有200万的包可以直接调用任何Web组件都可以变成桌面功能代码复用率示意一个真实案例我们团队曾需要给桌面应用增加Markdown编辑器。如果用Qt实现需要数周。但Electron下直接用toast-ui/vue-editor两小时就集成完毕。优势2真正的跨平台Electron一套代码可以生成平台输出格式分发渠道Windows.exe、.msi官网下载、Microsoft StoremacOS.dmg、.app、.pkg官网下载、Mac App StoreLinux.deb、.rpm、.AppImageAPT、Snap Store、Flathub平台差异处理示例// 同一个代码自动适配不同平台 const { app } require(electron) // 文件路径分隔符 const configPath app.getPath(userData) // Windows: C:\Users\用户名\AppData\Roaming\应用名 // macOS: /Users/用户名/Library/Application Support/应用名 // Linux: /home/用户名/.config/应用名 // 菜单栏差异 if (process.platform darwin) { // macOS应用菜单在屏幕左上角 app.dock.show() } else { // Windows/Linux菜单在窗口内 win.setMenu(menu) }优势3Web与原生能力的无感融合这是Electron最强大的地方——你可以在同一个代码文件中写// 这是一个完整的Electron功能片段 document.getElementById(save).addEventListener(click, async () { const content editor.getValue() // 1. 这是Web代码DOM操作 document.getElementById(status).innerText 保存中... // 2. 这是Node.js代码写文件 await fs.promises.writeFile(currentFilePath, content) // 3. 这是原生能力系统通知 new Notification(保存成功, { body: 文件已保存到 ${currentFilePath}, icon: icon.png }) // 4. 这是Electron原生API闪烁任务栏图标 win.flashFrame(true) // 5. 更新UI document.getElementById(status).innerText 已保存 })前端开发者不需要学习C、不需要了解Win32 API就能实现完整的桌面应用。七、Electron的三大缺点以及如何应对作为资深开发者我必须诚实地说出它的痛点缺点1内存占用高问题图示应对方案代码// 方案1后台窗口节流 const win new BrowserWindow({ webPreferences: { backgroundThrottling: true // 后台窗口降低帧率和定时器频率 } }) // 方案2窗口销毁时彻底释放 win.on(closed, () { win null // 解除引用让GC回收 }) // 方案3使用内存分析工具 // 在Chrome DevTools中 Memory - Take heap snapshot // 找出未释放的对象缺点2安装包体积大体积对比应用安装包大小安装后大小原生记事本1MB1MBQt计算器~5MB~15MB最小Electron应用~70MB~180MB典型Electron应用100-200MB300-500MB应对方案// electron-builder配置 - 启用最大压缩 { build: { compression: maximum, // 使用7z压缩比zip小30% asar: true, // 打包成asar格式 files: [ !**/*.map, // 排除source map !**/test/**, // 排除测试文件 !**/docs/** // 排除文档 ] } }缺点3启动速度慢启动流程耗时分析优化方案代码// 方案1先创建隐藏窗口 let win new BrowserWindow({ show: false, // 先隐藏 webPreferences: { preload } }) win.loadURL(app://index.html) // 准备就绪后再显示 win.once(ready-to-show, () { win.show() // 如果有需要再打开DevTools // if (isDev) win.webContents.openDevTools() }) // 方案2缓存编译结果 // 安装 v8-compile-cache require(v8-compile-cache) // 方案3预创建常用窗口VSCode模式 class WindowManager { constructor() { this.pendingWindows [] } preCreate() { // 后台提前创建常用窗口 const win new BrowserWindow({ show: false }) this.pendingWindows.push(win) } getWindow() { if (this.pendingWindows.length 0) { const win this.pendingWindows.pop() win.show() return win } return new BrowserWindow() } }八、什么时候应该不应该用Electron✅ 适合使用Electron的场景典型适用案例已有Web版本的产品直接复用70%的代码Slack、Discord、Figma都是这么做的需要跨平台的工具类应用Markdown编辑器、API测试工具、数据库客户端例Postman、TablePlus、Beekeeper Studio对界面交互要求高需要复杂动画、实时协作、Canvas绘图Electron可以使用任何Web动画技术快速迭代的创业产品Web前端可以直接转型桌面开发无需招聘C/C#团队❌ 不适合使用Electron的场景九、Electron vs Tauri新生代挑战者近年来Tauri成为热门替代方案这里做一个详细对比对比维度ElectronTauri后端语言Node.jsRust前端技术任意Web框架任意Web框架WebView内置Chromium系统原生WebView安装包大小~70MB起步~2MB起步内存占用~80MB起步~10MB起步Windows 7支持✅ 完全支持⚠️ 需要WebView2API丰富度⭐⭐⭐⭐⭐⭐⭐⭐生态成熟度⭐⭐⭐⭐⭐⭐⭐⭐学习成本低前端可上手中需要了解Rust选型建议追求最小体积 团队有Rust能力 → 选Tauri需要最大兼容性 团队纯前端 → 选Electron需要丰富API 快速开发 → 选Electron十、Electron的学习路线图如果决定学习Electron建议按这个路径十一、写在最后Electron的定位Electron不是银弹也不是玩具。它是一个务实的选择——让Web技术栈的团队能够以可接受的性能和体积代价交付跨平台桌面应用。什么时候应该认真考虑Electron当你的团队以Web前端为主当你需要在3-6个月内交付桌面产品当你愿意用200MB安装包换取80%的代码复用率时Electron就是最佳答案。数据支撑GitHub上Electron有110k star每周npm下载量超过1000万次全球有超过100万个Electron应用VSCode证明了它可以做到极致性能Figma证明了它可以承载复杂交互Notion证明了它适合现代SaaS产品

更多文章