PWA 概念及核心功能的基本介绍

目录

一. PWA 概念介绍

1.1 什么是 PWA?

1.2 为什么会出现 PWA?

1.3 如何判断一个 web 应用是 PWA?

二. PWA 核心功能

2.1 何谓 Service Worker

2.2 注册 Service Worker

2.3 Service Worker 常用事件

2.3.1 install

2.3.2 fetch 

2.4 Manifest

2.5 清单文件

2.6 添加到主屏

2.7 Push & Notification

2.7.1 何谓 推送/通知?

2.7.2 推送/通知 需要的授权

2.7.3 关于推送

三. PWA 发展趋势

3.1 PWA 优势

3.2 PWA 劣势


  • 在手机上浏览网页时,页面偶尔会出现弹窗,询问是否要将此网页保存到本地;
  • 如果选择了确定,在手机的主屏上就会出现一个新的 App,它就是刚才浏览的网页;
  • 这种 App 并非来自应用商店,却可以像使用 App 一样去使用或卸载它,它就是这篇文章的主角 ——— PWA

一. PWA 概念介绍

1.1 什么是 PWA?

  • 渐进式 web 应用(Progressive Web App),是 Google 2016 年提出概念、2017 年落地的 web 技术,渐进式 web 应用 就是 实现了和原生应用相近的用户体验的网页应用
  • PWA 不单指一种技术,也是一种思想和概念,它的目的是 —— 通过一系列的 Web 技术去优化网页应用;提升其安全性,性能,流畅性,用户体验等指标;最后达到用户使用网页应用,就像在用 原生App 一样的效果

1.2 为什么会出现 PWA?

  • 原生App 使用起来很流畅,性能好,安全性也可以很高,这是它很显著的优势
  • 但是缺点呢,也很明显,比如:
  1. 开发成本很昂贵
  2. 软件上线,版本更新都需要发布到不同的商店,并通过审核,对开发很不友好
  3. 对于用户来说,有些 APP 使用频率很低,但还是得去商店中下载大安装包;或者随着版本的更新,得卸载并更新
  • PWA 完美地避免了这些问题

1.3 如何判断一个 web 应用是 PWA?

  • 在安装方式上,PWA 与 原生App 有很大的不同
  • 在实际使用上,PWA 与 原生App 的差距非常小
  • 判断是否为 PWA 的思考方向如下:
  1. 可发现 —— 内容可以通过搜索引擎发现
  2. 可安装 —— 可以出现在设备的主屏幕
  3. 可链接 —— 可以通过 URL 分享它
  4. 独立于网络 —— 可以在 离线状态 或 网速很差 的情况下运行
  5. 渐进式 —— 在老版浏览器中仍可使用,在新版浏览器中可使用全部功能
  6. 可重用 —— 无论何时有更新的内容,它都可以发送通知
  7. 响应性 —— 在任何具有屏幕和浏览器的设备上,都可以正常使用(包括手机,平板电脑,笔记本,电视,冰箱等)
  8. 安全 —— 可以阻止第三方应用访问用户敏感数据

二. PWA 核心功能

2.1 何谓 Service Worker

  • Service Worker 是浏览器和网络之间的虚拟代理
  • Service Workes 运行在一个与 页面的 JavaScript 主线程 独立的线程上,它没有对 DOM 结构的访问权限,可以在不同上下文间 发送/接收 信息
  • 可分配给 Servic Worker 一些任务,使用基于 Promise 的方法在任务完成时收到结果
  • Service Worker 不仅提供离线功能,还提供包括处理通知,在单独的线程上执行繁重的计算等功能
  • Service Worker 可以控制网络请求,修改网络请求,返回缓存的自定义响应,或合成响应;因为强大,所以 Service Workers 只能在安全的上下文中执行(即 HTTPS )

2.2 注册 Service Worker

  • 浏览器支持 Service Worker
  • Service Worker 的 注册路径 决定了它的 默认作用页面的范围,也就是 scope
  • 如果希望改变它的作用域,可在 第二个参数 设置 scope 范围
  • 如果存放在网站根路径下,将会收到该网站的所有 fetch 事件
  if ("serviceWorker" in navigator) {
    // 浏览器支持 Service Worker
    navigator.serviceWorker
      .register("serviceWorker.js") // 这里可以接受第二个参数,用于设置 scope 范围
      .then(function (registration) {
        // 如果存放在网站根路径下,将会收到该网站的所有 fetch 事件
        console.log("ServiceWorker注册成功: ", registration.scope);
      })
      .catch(function (err) {
        console.log("ServiceWorker注册失败: ", err);
      });
  }
  • 注册完成后,serviceWorker.js 文件会自动下载、安装、激活

2.3 Service Worker 常用事件

2.3.1 install

  • install 事件发生在:浏览器安装并注册 Service Worker 时

  • event.waitUtil 用于在安装成功之前执行一些预装逻辑,建议只做一些轻量级和非常重要资源的缓存,以减少安装失败的概率,
  • Service Worker 会等到 waitUntil 内的代码执行完毕后,才开始安装,它返回一个 promise

  • 安装成功后,ServiceWorker 状态会从 installing 变为 installed

  • caches 是一个特殊的 CacheStorage 对象,它能在 Service Worker 指定的范围内提供数据存储的能力,
  • 如果所有的文件都成功缓存了,便会安装完成;如果任何文件下载失败了,那么安装过程也会随之失败
<script>
  var cacheName = "hello-pwa";

  // install 事件发生在: 浏览器安装并注册 Service Worker 时
  self.addEventListener("install", (event) => {
    // event.waitUtil 用于在安装成功之前执行一些预装逻辑
    // 建议只做一些轻量级和非常重要资源的缓存,以减少安装失败的概率
    // 安装成功后 ServiceWorker 状态会从 installing 变为 installed
    event.waitUntil(
      // caches 是一个特殊的 CacheStorage 对象
      // 它能在 Service Worker 指定的范围内, 提供数据存储的能力
      caches
        .open(cacheName)
        .then((cache) =>
          cache.addAll(
            [
              "/", // 一定要包含整个目录,不然无法离线浏览
              "./images/cat2.jpg",
              "./index.html",
              "./style.css",
            ]
            // 如果所有的文件都成功缓存了,便会安装完成
            // 如果任何文件下载失败了,那么安装过程也会随之失败
          )
        )
        .then(() => self.skipWaiting())
    );
  });
</script>

2.3.2 fetch 

  • Service Worker 会从缓存中请求所需数据,从而提供离线应用功能

  • 当应用发起一个 http 请求时,可以使用 fetch 事件
  • fetch 事件用于:拦截请求,并对请求作出响应
  • caches.match() 函数,用来检查 请求URL 是否匹配 缓存中已存在的内容;如果存在,就返回缓存资源;如果不存在,就通过网络来获取资源,并将资源存储到缓存中
  // Service Worker 会从缓存中请求所需数据,从而提供离线应用功能
  self.addEventListener("fetch", function (e) {
    event.respondWith(
      // caches.match() 函数,用来检查 请求URL 是否匹配 缓存中已存在的内容;
      // 如果存在,就返回缓存资源;
      // 如果不存在,就通过网络来获取资源,并将资源存储到缓存中
      caches.match(e.request).then(function (r) {
        return (
          r ||
          fetch(e.request).then(function (response) {
            return caches.open(cacheName).then(function (cache) {
              cache.put(e.request, response.clone());
              return response;
            });
          })
        );
      })
    );
  });

2.4 Manifest

  • 想成为可安装网站,需要的准备工作:
  1. 一份网页清单,填好正确的字段
  2. 网站的域必须是安全(HTTPS)的
  3. 一个本设备上代表应用的图标
  4. 一个注册好的 Service Worker,可以让应用离线工作(这仅对于安卓设备上的 Chrome 浏览器是必需的)

2.5 清单文件

  • 清单文件通常位于网页应用的根目录,包含很多有用的信息,比如:应用标题、应用图标路径、加载/启动画面的背景颜色等等
  • 这些信息在 浏览器安装 web 应用时、在主屏上显示应用时 需要的

  • 这些信息会以 JSON 的形式列出

  • 一份网页清单,最少需要 name、icon (icon 需要带有 src, size 和 type)、description、short_name、start_url

  • manifest.webapp,它是以前网页清单中常用的扩展名,在 Firefox OS 应用清单中很流行
  • 许多人使用 manifest.json 作为网页清单,因为内容是 JSON 格式的
  • 但是 .webmanifest 扩展名是在 W3C 清单规范中显示指定的,建议清单文件使用 .webmanifest 作为后缀
{
  "name": "Minimal PWA", //网站应用的全名
  "short_name": "PWA Demo", // 显示在主屏上的短名
  "description": "The app that helps you understand PWA",  // 应用描述
  "display": "standalone",  // 应用的显示方式:可以是全屏,独立,最小ui或者浏览器
  "start_url": "/",  // 应用启动的index文档
  "theme_color": "#313131", // ui的主题色,这是操作系统使用的
  "background_color": "#313131", // 背景色,用于安装程序时和启动应用时
  "icons": [
    {
      "src": "icon/lowres.webp",
      "sizes": "48x48",
      "type": "image/webp"
    },
    {
      "src": "icon/lowres",
      "sizes": "48x48"
    },
    {
      "src": "icon/hd_hi.ico",
      "sizes": "72x72 96x96 128x128 256x256"
    },
    {
      "src": "icon/hd_hi.svg",
      "sizes": "72x72"
    }
  ] // 确保有一个最适合用户设备的图标可以被选中
}

2.6 添加到主屏

  • “添加到主屏” 是移动端浏览器才有的,它利用网页清单中的信息,在设备主屏上显示应用图标和文字
  • 用户访问 PWA 时,会出现一个弹框提示用户 “是否安装此应用”,用户确认之后,应用就被安装到主屏了
  • 在某些移动端浏览器中,可以通过清单信息产生启动画面(在 PWA 启动时显示),图标、主题和背景色,用于创建这个启动画面
  • 在 Ios 上和 Android 手机上打开 Vue 官网,可以将其添加到设备主屏:

PWA 概念及核心功能的基本介绍


2.7 Push & Notification

2.7.1 何谓 推送/通知?

  • Push & Notification(推送和通知)通过 推送API 和 通知API 来实现
  1. 推送 —— 实现从服务端推送新的内容,而不需要客户端发起请求,它由应用的 Service Worker 实现
  2. 通知 —— 通过 Service Worker 向用户展示新信息,比如提醒用户应用更新了功能
  • 推送和通知,是在浏览器外部实现的,跟 Service Worker 一样;因此,即使应用被隐藏到后台,甚至应用关闭,我们仍能 推送/通知 到用户
  • 推送API 和 通知API 可以独立工作,也可以结合使用

2.7.2 推送/通知 需要的授权

  • 当用户同意授权,PWA 就可以实现 推送 + 通知,也就是说授权同时控制这两个
  • 用户授权的结果有三种,default(默认),granted(同意) 或者 denied(拒绝)
  var button = document.getElementById("notifications");
  console.log(button);
  button.addEventListener("click", function (e) {
    Notification.requestPermission().then(function (result) {
      if (result === "granted") {
        // randomNotification();
        console.log("授权");
      }
    });
  });

2.7.3 关于推送

  • 推送比通知要复杂,他的流程是这样的:
  1. 首先需要从服务端订阅一个服务;
  2. 之后服务端会推送数据到客户端应用;
  3. 接着应用的 Service Worker 负责接收到从服务端推送的数据,这些数据可以用来做通知推送,或者实现其他的需求

  • Service Worker 内存在 订阅服务器消息 的机制:registration.pushManager.getSubscription().then(/* ... */);

  • 用户订阅服务之后,为了让 PWA 接收到服务器推送的消息,我们需要在 Service Worker 文件里面监听 push 事件
  • self.addEventListener("push", function (e) {  /* ... */ });

  • 这个技术还处在非常初级的阶段
  • 从服务端角度来看,出于安全的目的,整个过程必须使用非对称加密技术进行加密
  • VAPID 可以给应用提供一层额外的安全保护

三. PWA 发展趋势

  • PWA 作为一个 2016 年才落地的新技术,经过四年的发展,基于 Chromium 的浏览器 Chrome 和 Opera 已经完全支持 PWA 了
  • 随着 iOS 11.3 的发布,iOS 正式开始支持 PWA
  • Windows Edge 也支持 PWA 了
  • 越来越多的游览器大厂,对 PWA 做出了支持和优化

3.1 PWA 优势

  • 无需安装下载,只要访问一次他的网址,将其添加到设备桌面,就可持续使用
  • 发布不需要提交到 app 商店审核,更新迭代版本也不需要审核
  • 现有的 web 网页都能改进为 PWA, 能很快上线,实现业务、获取流量
  • 不需要开发 Android 和 IOS 两套不同的版本

3.2 PWA 劣势

  • 浏览器对 PWA 的技术支持还不够全面, 没有任何览器能 100% 支持所有 PWA
  • 需要通过第三方库才能调用底层硬件(如摄像头)
  • 国内某些手机在 Android 系统上屏蔽了 PWA
上一篇:线程的基础


下一篇:mysql_26 _ 备库为什么会延迟好几个小时