Elytra
Blog2026

很多桌面应用为何自带浏览器引擎?从 Electron 到 WebView2 的二十年轮回

Electron 为何给每个应用塞一份 Chromium?WebView2、Tauri 在解决什么问题?IE 时代又告诉我们共享 Runtime 为何曾经是一场灾难。

随笔
GPT 5.6+1
electronwebviewbrowsertaurihistoryweb

装一个「设置面板」或「Markdown 编辑器」,安装包却动辄上百 MB——这类体积往往不是因为业务功能本身有多复杂,而是因为应用自带了一整套浏览器运行时

当然,并不是所有桌面应用都这样。Photoshop、大部分游戏、传统 Win32/Qt 工具通常不会各自打包一份 Chromium。但在跨平台桌面软件里,Electron 及其同类方案已经把「自带引擎」做成了非常普遍的路径:Discord、Slack、VS Code、Obsidian、Notion 桌面版、Teams……你电脑里很可能同时跑着好几份互不共享的 Chromium 副本。

证据不在任务管理器里——那里通常只显示应用名和内存占用,看不出引擎是否重复。更直观的是安装目录:一个极简的 Electron Hello World,空壳应用往往就有 100 MB 以上;成熟产品的安装包更大,其中 Chromium、V8、Node.js 与 Electron 框架本身占了相当大的比例。磁盘上,这几款应用各自携带的浏览器运行时叠加起来,往往比它们各自的 UI 与业务逻辑显眼得多。

这是过去十几年里一类很典型的取舍:开发效率换用户资源。

Electron 的做法是:为了用 HTML/CSS/JS 写界面,把 Chromium + V8 + Node.js 一并打进安装包,并继承 Chromium 的多进程模型——每个窗口通常还有独立的 renderer process。开发者换来的是跨平台 UI 与生态,用户付的账是安装体积、磁盘占用,以及多开应用时的内存压力。

于是一个很自然的问题出现了:

为什么不让系统维护一份 Chromium Runtime,需要嵌网页的应用共用?

其实非常合理。今天的 WebView2 / WKWebView / Android System WebView / Tauri,某种意义上正是在往这个方向走——只是适用范围、取舍和历史包袱各不相同。

核心结论

  • 讨论的是一类选择自带引擎的桌面应用(Electron、CEF 等),不是「所有 App」。
  • Electron:用磁盘和内存换开发者的确定性与兼容性。
  • WebView2 等共享 Runtime:系统维护一份自动更新的 Web 引擎,应用只带业务代码。
  • 引擎单一化(monoculture)Runtime 共享 是两回事——前者危险,后者合理。

哪些应用会自带浏览器引擎?

大致可以分成几类:

类型典型例子是否自带完整引擎
Electron 应用VS Code、Discord、Slack、Obsidian是,各带一份 Chromium
CEF 嵌入Spotify 桌面版、部分游戏启动器是,各带一份 Chromium
系统 WebView微信 PC 版部分界面、Tauri 应用否,链接系统 WebView
原生 UIOffice、Adobe、大部分游戏

所以问题不是「每个 App 都有一个浏览器」,而是:当越来越多工具选择 Web 技术栈做桌面 UI 时,重复打包浏览器运行时成了常态。

Electron 为什么偏偏要自带一份 Chromium?

因为它买到了一样开发者非常喜欢的东西:确定性。

Electron 开发者可以认为:

我的 App
 ├─ Chromium 128
 ├─ V8 x.x
 ├─ Node x.x
 └─ 我的网页代码

然后 Windows、macOS、Linux 上基本都是同一套环境。

不会出现:

用户 A:系统 WebView 太老
用户 B:CSS Grid 行为不一样
用户 C:系统升级后 WebView 更新,App 突然坏了
用户 D:公司电脑锁死了 5 年前版本

这其实和游戏打包 runtime 很像。你开发 Unity 游戏通常也不会说:「让用户电脑自己提供一个版本不确定的 Mono/CoreCLR 吧。」因为那会把兼容性问题转嫁给应用。

Electron 的哲学基本就是:

我宁可多占你 150 MB,也不要让你的系统环境决定我的程序是否能运行。

从开发者成本上看,这是极其划算的。从整个电脑生态看,就显得很浪费:

Discord       Chromium A(独立副本)
VS Code       Chromium B(独立副本)
Slack         Chromium C(独立副本)
Notion        Chromium D(独立副本)
Teams         Chromium E(独立副本)
Obsidian      Chromium F(独立副本)

它们的功能差异很大,但底层引擎却是同一类东西的多次复制。即便某个成熟产品(比如 VS Code)本身的扩展、语言服务、内置资源也占了不少空间,重复打包 Chromium 这件事仍然是真实存在的额外成本——不是「业务代码只有几 MB」那么简单,而是每多装一个 Electron 应用,就多一份运行时开销

「.NET Runtime 模式」:WebView2 真的出现了

微软的 WebView2 Evergreen Runtime 基本就是:

浏览器版的 .NET Runtime。

微软官方甚至明确把 WebView2 Runtime 类比成 .NET / Visual C++ Runtime。Evergreen 模式下,系统维护一份自动更新的 WebView2 Runtime,所有 App 共用;Windows 11 通常直接预装。

于是:

Windows

├── Edge / WebView2 Runtime
│       └── Chromium

├── App A ──┐
├── App B ──┼──→ WebView2
├── App C ──┤
└── App D ──┘

甚至当 Edge 和 WebView2 版本相同时,微软会对二进制做 hard-link,减少磁盘占用;已经加载的相关二进制还可能改善启动和内存表现。

这确实比「每个 Electron 应用各自拖一份 Chromium」优雅很多。

Tauri:接受系统 WebView 的取舍

Tauri 的一个核心设计就是:

我不带浏览器。用操作系统已经有的 WebView。

目前它大致是:

Windows → WebView2 → Chromium
macOS   → WKWebView → WebKit
Linux   → WebKitGTK → WebKit

Tauri 官方明确说明 WebView library 不会被打包到最终 executable,而是在运行时动态链接系统 WebView,所以应用会小很多。代价就是不同平台 WebView 的差异重新出现了。

ElectronTauri
浏览器引擎自带 Chromium使用系统 WebView
安装体积很小
跨平台一致性极高较低
引擎版本可控性极高较低
系统集成一般更自然
开发兼容性成本稍高

没有绝对胜负。

Electron 是拿用户的磁盘/内存换开发者时间。

Tauri/WebView 是拿开发者的一部分兼容性成本换用户资源。

那为什么操作系统不从一开始就这么干?

其实干过。

Windows 很早就有:

Internet Explorer

MSHTML / Trident

WebBrowser Control

任何 Win32 程序都可以嵌进去

也就是你今天设想的东西。

问题是……那个共享浏览器叫 IE。

于是灾难开始了。

为什么微软坚守 IE 那么多年?

这里有一个很讽刺的历史规律:

微软不是因为 IE 太差而无法抛弃 IE。

恰恰是因为 IE 曾经太成功,所以无法抛弃 IE。

90 年代末 IE 击败 Netscape 后,大量企业内部系统开始写成:

IE only
ActiveX
VBScript
MSHTML 特殊行为
IE Document Mode
IE 专属 DOM

银行内部系统、政府办公、ERP、OA、工厂管理、医院系统、公司 Intranet——全都可能依赖某个 IE bug。

于是出现一个可怕的问题:

IE6:  错误行为 X
开发者: // 根据错误行为 X 写了网站
微软:  IE7: 我们把 X 修正确了
客户:  「我们公司 17 年历史的 ERP 崩了。」

微软自己的 Edge 团队后来也明确总结过这个问题:很多网站依赖 IE 特有行为、旧 document mode 和 X-UA-Compatible;修复标准兼容性问题反而会破坏这些站点。

最终 IE11 甚至需要:

IE11
 ├─ IE11 Mode
 ├─ IE10 Mode
 ├─ IE9 Mode
 ├─ IE8 Mode
 └─ IE7 Compatibility Mode

浏览器里面带着浏览器考古遗址。

直到今天 Edge 里都还有 IE Mode:现代网页由 Chromium 渲染,而指定的老企业网页仍然调用 IE11 的 Trident/MSHTML,甚至支持 ActiveX。这足以说明当年的技术债有多恐怖。

微软真正的失误:IE6 成功之后

IE6 大约达到统治地位后,微软对浏览器的投入明显放缓。

而 Firefox、Safari、后来 Chrome 开始快速推动 HTML5、CSS3、更好的 JavaScript、标准 DOM、性能与开发工具。IE 则背着 ActiveX、Trident、企业兼容性、旧 Document Mode、Windows 深度绑定一路跑。

于是前端开发经典体验就变成:

/* Chrome */  正常
/* Firefox */ 基本正常
/* Safari */  调一下
/* IE */      ?????????

以及传奇般的 if IE6 / if IE7 / if IE8 / if IE9 …

这种跨浏览器不一致,确实长期消耗了大量开发者心力。这也是后来浏览器厂商非常重视 Interop 项目的原因——微软自己现在也把减少跨浏览器不一致列为核心目标。

微软中间还挣扎过一次:EdgeHTML

很多人会忘记:微软没有直接从 IE 跳到 Chromium Edge,而是:

IE / Trident

2015  Edge / EdgeHTML

2020  Edge / Chromium Blink

EdgeHTML 的想法其实挺理想主义:把 IE 二十年的历史包袱砍掉,做一个现代、独立、符合标准的浏览器引擎。微软当时还专门解释过:他们考虑过 WebKit,但担心整个 Web 变成单一引擎,也认为基于自己已有代码开发新引擎更快。

结果几年以后发现一个现实:维护浏览器引擎实在太贵了。

你要实现 HTML、CSS、JS、DOM、Canvas、WebGL、WebRTC、WebAudio、WebAssembly、Video、Fonts、Accessibility、Sandbox、GPU compositing、Network stack、DevTools、Security……

而 Chrome 市占率越来越高以后,又产生另一个问题:很多网站实际上变成「Chrome 能跑就上线」。EdgeHTML 遇到的网站 bug 越来越多。

于是微软 2018 年宣布换 Chromium,并明确把改善兼容性和简化开发者测试矩阵列为原因。

这是一个非常务实的投降:

我们为什么每年花巨大工程资源
重新实现一遍 Chromium 已经实现的东西?

那 Apple 为什么不也直接 Chromium?

因为如果 Chrome、Edge、Opera、Brave、Vivaldi、Safari、Firefox 全都用 Blink,那么实际上:

Web 就不再是开放标准,而会逐渐变成「Chromium 的行为就是标准」。

标准可能写着 A,Chromium 实现 B,结果 95% 用户看到 B。开发者就会写 if (worksInChrome) ship();,最后 B 就事实上成为标准。

这就是所谓 browser engine monoculture(浏览器引擎单一化)

所以保留 Blink、WebKit、Gecko 三支引擎,从整个 Web 的长期健康来看其实很重要。

Apple 的讽刺之处

Apple 在 iOS 上过去长期要求浏览器使用 WebKit。所以 Safari iOS、Chrome iOS、Firefox iOS、Edge iOS 很多时候其实只是不同 UI 的 Safari engine——这反而是另一种 monoculture

现在规则正在松动。Apple 当前的 App Review Guidelines 仍原则上要求浏览网页的 App 使用 WebKit,但提供 alternative browser engine entitlement;目前欧盟等特定地区已经允许符合条件的替代引擎。

所以 Apple 的逻辑主要不是「WebKit 是世界上最好的」,而更多是安全控制、功耗、系统集成、JIT 权限、进程隔离、App Store 管理与平台控制权。当然,这也给 Apple 带来了很大的争议。

两种「统一」,不能混为一谈

第一种统一:Runtime 分发——我赞成

Windows  → WebView2 Runtime
macOS    → WKWebView
Android  → Android System WebView

需要嵌网页的应用,不必各自塞一份完整的 Chromium。这就是现在的趋势。

第二种统一:只剩一个引擎——很危险

Web = Chromium

短期对开发者爽得不得了:只测 Chrome,完事。

长期却可能变成:Google 修改 Chromium → 整个 Web 被迫跟随。没有第二个实现去验证「这个到底是 Web 标准,还是 Chromium 特性?」

因此比较健康的状态反而是:

                    Web Standards

        ┌────────────────┼────────────────┐
        ↓                ↓                ↓
      Blink            WebKit           Gecko
        │                │                │
    Chrome/Edge        Safari          Firefox

然后通过 W3C、WHATWG、Web Platform Tests、Interop 等项目,让三者行为尽可能一致,而不是把三者变成一个。

绕了二十多年,又回到了起点

把上面的线索串起来:

1995   IE / MSHTML

       其实已经有系统共享 Web Runtime

       但 IE 变成兼容性灾难

2008+  Chrome 出现

2013   Electron

       一类应用开始各自打包 Chromium

       兼容性极好,体积膨胀

2020+  WebView2

       共享 Chromium Runtime

       兼容性 + 小体积

       Tauri

       直接利用系统 WebView

对选择 Electron 路线的应用来说,各自携带一份 Chromium 确实是一种工程上的奢侈。

「系统提供共享、自动更新的 Web Runtime」,对需要嵌网页、又不想重复打包引擎的场景,是更现代、更优雅的方向。

某种意义上,我们绕了二十多年,又回到了一开始想到的那个设计——只是范围更清楚了:

操作系统维护一个类似 CLR 的现代 Web Runtime;需要渲染网页的那一类应用链接它,其余应用照旧走原生 UI。

区别只是这一次终于学会了:Runtime 必须独立于 OS 快速更新、保持强兼容、自动打安全补丁。

这才是 WebView2 相比当年 IE WebBrowser Control 真正关键的进步。

On this page