2018年,我第一次听到Electron,当时的反应和很多人一样:
"用网页技术写桌面应用?这不就是套个浏览器壳子吗?能好用吗?"
这个偏见在很长时间里影响了我。直到后来,我发现自己每天都在用的VSCode、Slack、Figma、Notion,竟然都是Electron写的。
如果这些产品都在用,那一定不只是"套壳"那么简单。
官方的定义很简洁:
Electron是一个使用JavaScript、HTML和CSS构建跨平台桌面应用程序的框架。
但这句话太抽象了。让我们用一张图来看清楚Electron的架构:
我更喜欢用这个公式来理解它:
Electron = Chromium + Node.js + 原生API
拆开来看:
div、
button、
flexbox
Node.js 调用系统能力 读写文件、执行命令、访问数据库
fs.readFile()、
child_process.exec()
原生API 桌面集成 系统托盘、全局快捷键、通知
Tray、
globalShortcut、
Notification
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(() => ) }) // 所有窗口关闭时退出应用(除了macOS) app.on('window-all-closed', () => )
3. preload.js(预加载脚本 - 安全桥接)
const { contextBridge, ipcRenderer } = require('electron') // 安全地暴露API给渲染进程 contextBridge.exposeInMainWorld('electronAPI', )
4. index.html(渲染进程 - 这就是普通的Web页面!)
我的第一个Electron应用
欢迎使用Electron
这是一个真正的桌面应用!
点击按钮,结果会显示在这里...
` } document.getElementById('fileBtn').onclick = async () => { // 这里调用的是Node.js的文件读取能力 const content = await window.electronAPI.readFile('package.json') output.innerHTML = `
${content}` }
关键理解:
index.html里的代码看起来就是普通前端代码,但它能调用window.electronAPI.getSystemInfo()------这是纯Web页面做不到的。
很多人用了很久都不知道这些产品是Electron写的:
这些产品的共同点:
- 需要快速迭代(Web技术开发效率高)
- 需要跨平台(Windows/macOS/Linux一套代码)
- 对界面交互有较高要求(CSS动画、Canvas渲染)
- 有Web版本,代码复用率高
这是我给团队做技术选型时用的决策矩阵:
注: Tauri是较新的替代方案,使用系统WebView而非Chromium,体积更小但兼容性略弱。
决策流程图
决策建议:
- 选Electron:需要快速迭代、跨平台、有Web技术栈积累
- 选Qt/C++:需要极致性能(游戏引擎、CAD软件)、或嵌入式设备
- 选WPF:只做Windows、有C#技术栈、需要深度系统集成
- 选Tauri:追求小体积、团队熟悉Rust、不需要老平台支持
优势1:Web技术栈的杠杆效应
前端生态的价值:
- Vue、React、Svelte等框架直接可用
- npm上有200万+的包可以直接调用
- 任何Web组件都可以变成桌面功能
代码复用率示意:
一个真实案例:
我们团队曾需要给桌面应用增加Markdown编辑器。如果用Qt实现,需要数周。但Electron下,直接用@toast-ui/vue-editor,两小时就集成完毕。
优势2:真正的跨平台
Electron一套代码可以生成:
.exe、
.msi 官网下载、Microsoft Store
macOS
.dmg、
.app、
.pkg 官网下载、Mac App Store
Linux
.deb、
.rpm、
.AppImage APT、Snap Store、Flathub
平台差异处理示例:
// 同一个代码,自动适配不同平台
const { app } = require(‘electron’)
// 文件路径分隔符 const configPath = app.getPath(‘userData’) // Windows: C:Users用户名AppDataRoaming应用名 // macOS: /Users/用户名/Library/Application Support/应用名 // Linux: /home/用户名/.config/应用名
// 菜单栏差异 if (process.platform === ‘darwin’) { // macOS:应用菜单在屏幕左上角 app.dock.show() } else
优势3:Web与原生能力的无感融合
这是Electron最强大的地方------你可以在同一个代码文件中写:
// 这是一个完整的Electron功能片段
document.getElementById(‘save’).addEventListener(‘click’, async () => `,
icon: 'icon.png'
})
// 4. 这是Electron原生API(闪烁任务栏图标) win.flashFrame(true)
// 5. 更新UI document.getElementById(‘status’).innerText = ‘已保存’ })
前端开发者不需要学习C++、不需要了解Win32 API,就能实现完整的桌面应用。
作为资深开发者,我必须诚实地说出它的痛点:
缺点1:内存占用高
问题图示:
应对方案代码:
// 方案1:后台窗口节流
const win = new BrowserWindow({ webPreferences: {
backgroundThrottling: true // 后台窗口降低帧率和定时器频率
} })
// 方案2:窗口销毁时彻底释放 win.on(‘closed’, () => { win = null // 解除引用,让GC回收 })
// 方案3:使用内存分析工具 // 在Chrome DevTools中 Memory -> Take heap snapshot // 找出未释放的对象
缺点2:安装包体积大
体积对比:
应对方案:
// 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’, () => )
// 方案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()
return new BrowserWindow()
} }
✅ 适合使用Electron的场景
典型适用案例:
- 已有Web版本的产品
- 直接复用70%+的代码
- Slack、Discord、Figma都是这么做的
- 需要跨平台的工具类应用
- Markdown编辑器、API测试工具、数据库客户端
- 例:Postman、TablePlus、Beekeeper Studio
- 对界面交互要求高
- 需要复杂动画、实时协作、Canvas绘图
- Electron可以使用任何Web动画技术
- 快速迭代的创业产品
- Web前端可以直接转型桌面开发
- 无需招聘C++/C#团队
❌ 不适合使用Electron的场景
近年来Tauri成为热门替代方案,这里做一个详细对比:
选型建议:
- 追求最小体积 + 团队有Rust能力 → 选Tauri
- 需要最大兼容性 + 团队纯前端 → 选Electron
- 需要丰富API + 快速开发 → 选Electron
如果决定学习Electron,建议按这个路径:
Electron不是银弹,也不是玩具。
它是一个务实的选择——让Web技术栈的团队能够以可接受的性能和体积代价,交付跨平台桌面应用。
什么时候应该认真考虑Electron?
当你的团队以Web前端为主,当你需要在3-6个月内交付桌面产品,当你愿意用200MB安装包换取80%的代码复用率时,Electron就是**答案。
数据支撑:
- GitHub上Electron有110k+ star
- 每周npm下载量超过1000万次
- 全球有超过100万个Electron应用
- VSCode证明了它可以做到极致性能
- Figma证明了它可以承载复杂交互
- Notion证明了它适合现代SaaS产品
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/255855.html