把它叫「WebView」掩盖了它的本质。它不是一块画 HTML 的廉价矩形,而是整套装进内存的浏览器引擎——一个为每个托管小程序都开一个的流量 App,是在一遍遍替这台引擎交租。账单以白屏、重启、和用户不再回来这种形式到账。

两个平台,同一笔税

在 Android 上,谷歌自己的文档说得很直白:WebView「内存占用很大」,因为它本质上是一整套带复杂多进程架构的 Chromium 浏览器引擎。网页内容跑在独立的沙箱渲染进程里;App 进程只托管视图和浏览器侧逻辑。在 iOS 上,每个 WKWebView 都会起一个自己的 WebContent 进程。移动端稳定性公司 Embrace 的说法是:创建一个 WebView 等于「在你的 App 里再启动一个应用,并额外加上两个进程」。没有规模经济:一个 WebView 是三个系统进程,两个是五个,三个是七个。你开得越多越卡,也离被系统杀掉越近。

数字并不小

空白的 WebView 也不免费。实测占用:空白页 Android 约 50–80 MB、iOS 50–70 MB;简单列表 100–120 MB / 80–100 MB;电商详情页 Android 150–200 MB、iOS 120–150 MB;直播或 SPA 页 180–300 MB。谷歌 MemoryLab 的实测里,一个渲染进程仅几次 JavaScript 分配就跳到约 55 MB。某小程序平台的实测压测发现,每个 WebView 实例都是独立的 WebKit 进程、背着 80–150 MB 的基线——「这是 WebKit 的开销,不是我们的,没有任何开关能把它变小」。

你复现不了的崩溃

这正是它变成稳定性事故的地方。在那同一份小程序压测里,iPhone 15 发布构建下,1 个后台 WebView 稳定、5 个稳定,但 10 个就被 jetsam 了——约一秒内被系统杀掉,主机总内存约 1.0–1.2 GB。在小设备上推算很残酷:iPhone SE(第三代,4 GB)只能扛 1–2 个;SE(第二代,3 GB)只能扛 0–1 个。iOS 上一旦越过 WebContent 进程的内存硬上限,系统毫不商量地杀掉它——用户看到的是白屏。Android 上低内存杀手会独立终止渲染进程,不处理的话回来就是同一块白屏。Embrace 的经验法则:轮播图在内存里绝不超过两个 WebView。对一个托管着数百个商家页的流量 App 来说,一个重页就足以把整个 App 挤到 OOM——被迫重启、会话丢失、购物车丢失、用户流失。

runtime 的解法

宿主自有 runtime 拒绝为每个程序都起一整套浏览器引擎。它不把每个小程序变成一个沉重的 WebView 进程,而是池化并复用一组数量有界的视图、在平台允许处共享一个渲染进程,并让常见的轻量程序——结账、表单、内容卡——通过单一共享 runtime 上下文拿到远比「N 个独立引擎」小得多的开销。宿主对每个小程序、对整个目录执行内存预算,复用实例而非泄漏它们,并以优雅降级取代被系统杀掉。单个商家的重页,再也无法把整个 App 一起拖下水。

维度WebView宿主自有 runtime
每屏成本整套引擎,每屏 50–200+ MB共享 runtime,有界、池化
扩展方式无规模经济,N 引擎 = N 倍开销单一共享上下文,按程序封顶
最坏情况Jetsam / 渲染进程被杀 → 白屏预算强制,优雅降级
爆炸半径一个重页拖垮整个 App按小程序隔离
实例生命周期不手动销毁就泄漏由宿主池化、复用

本系列的贯穿主线是控制权。WebView 让你开一块屏,却把内存账单——和崩溃——交给了操作系统。runtime 让你自己定预算。对于一个目录里是数百个别人页面的平台,这道预算,就是流畅 App 与畅销机型上白屏之间的那条线。

参考来源