PWA的非主流尝试:创建一个‘鸡肋’应用

1,097 阅读6分钟

最近接手维护一个海外Web,需要用到PWA技术,虽说这玩意面世得有七八年了,但一直不温不火,尤其国内几乎没啥浏览器支持,也鲜有人用。借机学了吧PWA,记录下。

目录

  1. PWA是什么

  2. 有什么优势

  3. 制作一个PWA应用

    manifest.json 配置文件

    ServerWorker.js

  4. 自定义安装

  5. 局限性及现状

  6. 相关文档

PWA 是什么

PWA(Progressive Web Apps) 是Google发明的一项Web技术,简单来说,是对普通html5网站的以下几项增强,目的是让网站变的像App:

  1. 可在桌面安装同原生app一样的图标,使用该图标打开的网站无任何浏览器UI,看起来就是原生APP,并且支持沉浸式状态栏、支持桌面图标图片和名称自定义等,虽然实际上仍是使用浏览器打开的一个网站。
  2. 在一定程度上支持无网络离线使用:通过拦截网络请求设置和获取缓存实现。
  3. 支持消息推送通知等,就和app一样,而且支持桌面图标上显示消息badge。
  4. 支持后台进程,即便压根没有打开该网站,例如后台下载音视频、播放音乐等。

PWA 有什么优势

从上述描述也能看出,最大的优势就是像App,没有浏览器地址栏、没有浏览器工具栏,如果网页本身是模仿app界面,那么从桌面图标打开后,几乎和原app一毛一样,难以区分。对于轻型app,体验也接近。

无需上架app商店,无需庞大安装体积,还能完整保留Web的跨平台、即时更新。

手机端和PC端均支持,前提是使用支持PWA的浏览器.

怎样制作一个PWA应用

PWA本质上就是一个网站,制作方式和普通网站一样,html5+js+css,只不过需额外增加一个 json 配置文件,用于定义PWA应用的名称、图标、安装方式等元信息。

如果想实现自定义安装,就写一段安装代码,在支持PWA的浏览器上,默认已提供安装按钮。手机浏览器一般隐藏在菜单的“安装”中。pc浏览器一般显示在地址栏右侧。

image.png

image.png

同时再增加一个js文件实现Service worker,用于监听和拦截网络请求,完成缓存的设置、读取,实现离线支持。

如果有需要,还可以继续在该js中实现 消息推送、系统通知、后台任务。

  1. 创建 manifest.json 配置清单文件

清单文件中有非常多的属性可设置,最简单配置只需4个元素

{
  "name": "我的第一个PWA",
  "short_name":"我的PWA",
  "icons": [
    {
      "src": "icons/512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url":".",
  "display":"standalone"
}


name 代表安装后显示的图标名称

short_name 如果已填写了name的话,这项可以不设置

在清单中至少要提供 short_name 和 name 中的一个。如果同时提供,系统会在用户安装应用时使用 name,并在用户的主屏幕、启动器或空间有限的其他位置使用 short_name

icons 是要显示的图标的图片信息对象数组,至少要包含一个512尺寸的图片。src:相对于manifest文件的图片路径,type: 图片mime类型

start_url是启动页面url,一般为./

display 代表启动方式,一般填写 standalone即可,表示作为一个独立应用启动。

完整的清单可查看文档 developer.mozilla.org/zh-CN/docs/…

  1. 创建 Service worker

名字看起来似乎复杂,其实就是一个简单js文件,当然如果想实现完美的体验,例如后台通知、推送、同步等,那确实能搞得很复杂, 这里只演示一个最简单的PWA应用所需的js实现。

一个最简单的js文件,只需要监听fetch事件即可,即便监听后什么也不干。


// 监听install事件
self.addEventListener('install', function (e) {
    console.log('Service Worker 状态: install');
});

// 监听activate事件
self.addEventListener('activate', function (e) {
    console.log('Service Worker 状态: activate');
});

self.addEventListener('fetch', function (e) {
    // 需要缓存的xhr请求
    console.log("fetch 事件")
});

将以上代码保存为 sw.js

注意出于安全考虑, ServiceWorker 只允许在 https 网站上使用,所以也决定了PWA只支持https网站

  1. 在 网页的 head 区域引入 manifest.json和sw.js,一个最简单的PWA应用就算完成了
<link rel="manifest" href="/manifest.json">
<script src="/sw.js"></script>    

在浏览器中(建议chromeedge浏览器)打开该网站,没意外的情况下,地址栏右侧会看到安装图标,点击会弹出一个安装提醒

image.png

安装后,桌面会多出一个应用图标。手机端也一样

image.png

image.png

自定义安装代码

默认需要点击浏览器中提供的安装按钮,pc端比较明显,一般在地址栏右侧中显示,但手机端浏览器藏的比较深,需要从菜单中进入找“添加到手机”或“安装”。

有时想在页面中悬浮一个按钮,提示用户可以安装到桌面,此时可以在 beforeinstallprompt 事件中实现自定义提示。

假如首页是index.html, 先添加一个悬浮按钮

<button id="install" hidden style="position: fixed;
    bottom: 67px;
    left: 50%;
    margin-left: -100px;
    height: 35px;
    width: 200px;
    font-size: 16px;
    text-align: center;
    background: #03A9F4;
    color: #fff;
    border: 0;
    line-height: 35px;
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.2);">Install PWA</button>

然后监听 beforeinstallprompt事件


    let installPrompt = null;
    const installButton = document.querySelector("#install");
    window.addEventListener("beforeinstallprompt", function(e) {
            e.preventDefault();
            installPrompt = e;
            installButton.removeAttribute("hidden");
    });
    installButton.addEventListener("click", async () => {
            if (!installPrompt) {
                    return;
            }
            installButton.setAttribute("hidden", "");
            let result = await installPrompt.prompt();
            console.log(`Install prompt was: ${result.outcome}`);
            installPrompt = null;
    });

image.png

点击就会弹出安装提示。

可能有jy要问,直接在window.addEventListener("beforeinstallprompt 中 调用 e.prompt() 不就可以了吗?然而这是不可以的,出于安全考虑,必须在用户的主动点击中才可触发该操作。

PWA的局限性

PWA相对于普通html5确实有一定优势,但作用又不是特别大,形同鸡肋,加之国内浏览器普遍不支持,用者更是寥寥。

相对来说,chrome、firefox、Safari对PWA的支持比较好,在国外有一定应用,尤其是Google Play 商店可上架PWA应用,对于在Google play上架App困难的,倒是可以考虑使用PWA替代。

浏览器支持:尽管主流浏览器如Chrome、Firefox和Safari支持PWA,但国内普遍不支持。

性能:在一些低端或老旧的移动设备上,PWA可能无法提供与高端设备相同的性能体验,毕竟本质还是Web。

集成度:无法完全利用移动设备的硬件特性。

用户习惯:用户可能更习惯于从应用商店下载应用,而不是通过Web访问PWA。

必须使用https:虽然目前https网站已不成问题,但多少也算是一个限制吧。

相关文档

MDN developer.mozilla.org/zh-CN/docs/…

Learn PWA web.dev/learn/pwa