添加到主屏幕提示:PWA 安装提示在 Android 与 iOS 上怎么工作(2026)
添加到主屏幕提示:PWA 安装提示在 Android 与 iOS 上怎么工作(2026)
添加到主屏幕提示,是渐进式网页应用(PWA)从一个浏览器标签页,变成用户设备上一个真实图标的那一刻。它也是多数 PWA 安装漏斗真正漏水的地方——因为这个提示在 Android 和 iOS 上的行为完全不同,而且两边都不是开发者第一次接触时预期的样子。
这篇讲清:什么会触发提示、怎么控制它、为什么 iOS 上压根没有提示,以及怎么衡量这套东西到底有没有起作用。
两个平台,两套毫不相干的机制
不存在一个跨平台的「添加到主屏幕」API。存在的是两套互不相干的系统,只不过最后产出的图标看起来差不多:
|
|
Chromium 系浏览器(Android、桌面) |
iOS / iPadOS 上的 Safari |
|---|---|---|
|
可否代码触发提示 |
可以,通过 |
不可以 |
|
由谁发起 |
你的代码,或浏览器自己的 UI |
用户手动 |
|
安装路径 |
浏览器弹窗里一次点击 |
分享菜单 → 添加到主屏幕 |
|
能否检测是否符合条件 |
可以 |
无法直接检测 |
下面所有内容,都是这张表的推论。
Chromium 路径:beforeinstallprompt
在 Chromium 系浏览器上,当站点满足「可安装条件」时,浏览器会先抛出一个 beforeinstallprompt 事件,而不是立刻弹自己的 UI。这个事件就是让你决定什么时候开口问的钩子。
可安装条件
大体上,浏览器要求:
- 站点走 HTTPS。
- 引入了 web app manifest,其中至少包含 name 或 short_name、
start_url、取值为standalone/fullscreen/minimal-ui的display,以及图标(惯例上包含 192px 与 512px 两档)。 - 注册了 service worker。Chrome 历来要求它带
fetch处理器,但具体要求在不同版本间有过调整。 - 应用尚未被安装。
正因为这些细节在浏览器版本之间变过,任何成文清单——包括这一份——都不该当作最终依据。请对照当前 Chrome 官方文档,并打开 DevTools 的 Application 面板,它会明确告诉你这个站点具体卡在哪一条上。
控制提示出现的时机
默认行为通常不是你想要的,所以标准做法是:拦下事件、先存起来,等用户真正产生投入感的时刻再触发。
let deferredPrompt = null;
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault(); // 阻止浏览器此刻弹自己的提示
deferredPrompt = e; // 存下来待用
showYourOwnInstallButton(); // 你自己的 UI、你自己的时机
});
installButton.addEventListener('click', async () => {
if (!deferredPrompt) return;
deferredPrompt.prompt(); // 必须紧跟用户手势
const { outcome } = await deferredPrompt.userChoice;
trackInstallOutcome(outcome); // 'accepted' 或 'dismissed'
deferredPrompt = null; // 事件是一次性的
});有三条约束最容易把人绊倒:
prompt()必须在用户手势的响应里调用。放在定时器里或页面加载时调,会被拒绝。- 事件是一次性的。弹过一次,这个实例就用完了;想再问,需要浏览器再抛一次新的
beforeinstallprompt。 - 调了
preventDefault()却始终没调prompt(),等于用户什么都看不到。拦下事件之后忘了露出自己的按钮,就等于悄悄把安装能力整个关掉了。这是个相当常见的 bug。
确认安装完成
window.addEventListener('appinstalled', () => {
hideYourInstallButton();
trackInstalled();
});iOS 路径:根本没有提示
在 iOS 与 iPadOS 上,Safari 不会抛出 beforeinstallprompt,也不提供任何触发安装的 API。用户必须自己打开分享菜单、选择添加到主屏幕。
于是你只剩一个选项:引导式 UI。检测用户处于 iOS Safari 且尚未运行在独立模式下,然后展示一个小而可关闭的提示,指向分享按钮,并把两步操作写清楚。
几点实操建议:
- 必须可关闭,而且要记住用户关过。每次浏览都回来的横幅,比没有横幅更糟。
- 在用户产生一定投入之后再展示,别在首屏渲染时就弹。
- 自 iOS 16.4 起,从主屏幕启动的 Web 应用支持了 Web 推送,这实质性地增强了「值得安装」这件事的说服力。
- iOS 上的第三方浏览器历来走同一套底层引擎,因此其行为通常跟随 Safari,而非 Chromium。
检测「是否已经安装」
两个平台都支持同一套判断,它也是绝大多数安装分析的基础:
const isStandalone =
window.matchMedia('(display-mode: standalone)').matches ||
window.navigator.standalone === true; // 较老的 iOS 信号用它对已安装用户屏蔽安装 UI,同时把它当作分母,衡量你的流量里有多少是以安装态运行、多少还留在标签页里。
安装提示为什么转化不好
添加到主屏幕提示转化差时,原因通常是下面几条之一:
- 问得太早。价值还没交付就在首屏弹提示,是最常见的错误,没有之一。
- 没给理由。「安装我们的应用」是一个请求;「放到主屏幕,离线也能秒开」才是一个理由。
- 拦下了却再没露出来。就是上面那个
preventDefault()的 bug。 - 压根不满足可安装条件。manifest 拼写错误或缺一档图标尺寸,会让事件永远不触发,而且是静默的。DevTools 会告诉你是哪一条。
- 把 iOS 当成 Android 对待。没有引导式 UI,就意味着整个 iOS 受众根本不会安装。
这个提示在更大的分发决策里处于什么位置
安装提示只是「你的应用如何触达用户」这个更长决策链的最后一步。如果你还在权衡取舍,PWA vs APK 讲了 Android 分发在实操上的差异,PWA vs 原生应用 则覆盖了成本、性能与分发的整体图景。
常见问题
iOS 上能用代码触发添加到主屏幕提示吗?
不能。iOS 上的 Safari 不提供任何编程式安装 API。唯一的做法是用引导式 UI,带用户走「分享 → 添加到主屏幕」。
Android 上 beforeinstallprompt 一直不触发,为什么?
通常是站点没满足可安装条件,或者已经安装过了。打开 DevTools → Application → Manifest,它会报出具体卡住的原因。
安装提示可以弹多次吗?
每个 beforeinstallprompt 事件只能用一次。浏览器再抛新事件时你可以再问,但用完的事件无法重放;而且反复骚扰同一个用户,是让自己的横幅被永久无视的好办法。
一定要有 service worker 才会出现提示吗?
在 Chromium 上,注册 service worker 历来是可安装条件的一部分,具体要求随版本有变化。请以当前官方文档和 DevTools 的可安装性报告为准,别凭假设。
PWA 安装量该怎么衡量?
把三个信号结合起来:你自己提示返回的 userChoice 结果、appinstalled 事件,以及后续访问时的独立模式检测。第三个最可靠——因为它同时能捕捉到那些通过浏览器自带 UI(而非你的按钮)完成的安装。


