PWA 从入门到实践开发
了解 PWA
PWA(Progressive Web App)渐进式 Web 应用程序
Webpack、Rollup 等打包工具
Babel、PostCss 等转译工具
Typescript 等可转编译为 JavaScript 的编程语言
React 、Angular、Vue等现代 web 前端框架
同构 JavaScript 应用
Web 应用体验依然不佳
- 网页资源下载带来的网络延迟
- Web 应用依赖于浏览器作为入口
- 没有好的离线使用方案
- 没有好的消息通知方案
PWA(Progressive Web App)
- 显著提高应用加载速度
- Web 应用可以在离线环境下使用
- Web 应用能像原生应用一样被添加到主屏
- Web 应用能在未被激活时发起推送通知
- Web 应用与操作系统集成能力进一步提高
PWA 和原生 App 的差异
‘’ | 安装方式 | 访问入口 | 通知服务 | 开发迭代 |
---|---|---|---|---|
PWA | 在线、自动安装 | 图标、URL | 通知服务 | Web,一次开发,多平台可用,无须发版 |
普通 NavtiveApp | 应用商店 | 图标、相关调起 | 可通知服务 | 分平台,需发版 |
PWA 的支持情况
- Chrome、Oprea、Firefox 都已经实现了 PWA 所需的所有关键技术,Edge所有特性都已经处于【正在开发中】的状态。
- Safari,尤其是在 iOS 上,四个关键 API 都未得到支持,而且由于平台限制,第三方浏览器也无法在 iOS 上支持。
- 庆幸的是 Service Worker 与 Web App Manifest 纷纷列入了【正在考虑】的API 中,相信在不久的将来在 iOS 上也能体验 PWA。
PWA 特性
- 渐进增强
- 响应式用户界面
- 不依赖网络连接
- 类原生应用
- 持续更新
- 安全
- 可发现
- 再次访问
- 可安装
- 可连接性
PWA关键技术
- Web APP Manifest
- Service Worker
- Cache Storage API
- Push Notification
Web APP Manifest
Web APP Manifest,即通过一个清单文件向浏览器暴露 web 应用的元数据,包括名字、icon的 URL 等,以备浏览器使用,比如在添加至主屏或推送通知时暴露给操作系统,从而增强 web 应用与操作系统的集成能力。
- 可以添加到桌面,有唯一的图标和名称
- 有启动时界面,避免生硬的过渡
- 隐藏浏览器相关UI,比如地址栏等
使用 Web APP Manifest
- 在项目目录下创建一个 manifest.json 文件
- 在 index.html 中引入 manifest.json 文件
- 在 manifest.json 文件中提供常见的配置
- 需要在 https 协议 或者 http://localhost 下访问项目
1 | <link rel="manifest" href="manifest.json"> |
通过 http-server 开启本地服务,访问 index.html 文件
常用属性
- name:用于指定应用的名称,安装横幅提示的名称,和启动画面中的文字。
- short_name:应用的短名称,用于主屏幕显示
- icons:用于指定可在各种环境中用作应用程序图标的图像对象数组,144×144
- scope:定义了 web 应用的浏览作用域,比如作用域外的 URL 就会打开浏览器而不会在当前 PWA 里继续浏览。
- start_url:定义了一个 PWA 的入口页面。
- orientation:锁定屏幕旋转
- theme_color/background_color:主题色与背景色,用于配置一些可定制的操作系统 UI 以提高用户体验,比如 Android 的状态栏、任务栏等。
- display:用于指定 web app 的显示模式
Service Worker
- 一旦被 install,就永远存在,除非被手动 unregister
- 用到的时候可以直接唤醒,不用的时候自动睡眠
- 可编程拦截代理请求和返回,缓存文件,缓存的文件可以被网页进程取到(包括网络离线状态)
- 离线内容开发者可控
- 必须在 HTTPS 环境下才能工作
- 异步实现,内部大都是通过 Promise 实现
演变过程
- LocalServer
- Application Cache
- Service Worker
Service Worker 生命周期
- install 事件会在 service worker 注册成功的时候触发,主要用于缓存资源
- activate 事件会在 service worker 激活的时候触发,主要用于删除旧的资源
- fetch 事件会在发送请求的时候触发,主要用于操作缓存或者读取网络资源
如果 sw.js 发生了改变,install 事件会重新触发
activate 事件会在 install 事件后触发,但是如果现在已经存在 service worker 了,那么就处于等待状态,直到当前 service worker 终止。
可以通过 self.skipWaiting() 方法跳过等待,返回一个 promise 对象。
可以通过 event.waitUntil() 方法扩的参数是一个 promise 对象,会在 promise 结束后才会结束当前生命周期函数,防止浏览器在异步操作之前流停止了生命周期。
service worker 激活后,会在下一次刷新页面的时候生效,可以通过 self.clients.claim() 立即获取控制权。
Service Worker 使用
- 在 window.onload 中注册 service worker,防止与其他资源竞争
- navigator 对象中内置 service worker 属性
- service worker 在老版本的浏览器中不支持,需要进行浏览器兼容 if(‘serviceWorker’ in navigator){}
- 注册 service worker navigator.serviceWorker.register(‘./sw.js’) ,返回一个 promise 对象
1 | window.onload = function(){ |
Service Worker 缓存策略
Cache Storage
cacheStorage:接口表示 Cache 对象的存储。配合 service worker 来实现资源的缓存
cache 基本使用
caches api:类似于数据库的操作
- caches.open(cacheName).then(function(cache){}):用于打开缓存,返回一个匹配 cacheName 的 cache 对象的 promise,类似于连接数据库
- caches.keys():返回一个 promise 对象,包括所有的缓存的 key(数据库名)
- caches.delete(key):根据 key 删除对应的缓存(数据库)
cache 对象常用方法(单条数据的操作)
- cache 接口为缓存的 Request/Response 对象提供存储机制
- cache.put(req,res):把请求当成 key,并且把对应的响应存储起来
- cache.add(url):根据 url 发起请求,并且把响应结果存储起来.
- cache.addAll(url):抓取一个 url 数组,并且把结果都存储起来
- cache.match(req):获取 req 对应的 response
1 | <!-- index.html --> |
1 | // manifest.json |
1 | // sw.js |
Push Notification
- Push API 的出现则让推送服务具备了向 web 应用推送消息的能力
- Push API 不依赖 web 应用与浏览器 UI 存活,所以即使是在 web 应用与浏览器未被用户打开的时候,也可以通过后台进程接受推送消息并调用 Notification API 向用户发出通知。
- Notification.permission 可以获取当前用户的授权情况
- Default:默认的,未授权
- Denied:拒绝的,如果拒绝了,无法再次请求授权,也无法弹窗提醒
- Granted:授权的,可以弹窗提醒
- 通过 Notification.requestPermission() 可以请求用户的授权
- 通过 **new Notification(‘title’,{body:””,icon:””})**可以显示通知
- 在授权通过的情况下,可以在 service worker 中显示通知 self.registration.showNotification(‘你好’,{body:’msg’})
1 | // sw.js |
常见的缓存策略
- 对于不同的数据,需要不同的缓存策略
- 本地的静态资源,缓存优先
- 对于需要动态更新的数据,网络优先
避免缓存跨域资源
由于更新机制的问题,如果 service worker 缓存了错误的结果,将会对 web 应用造成灾难性的后果。
- 响应状态码为200;避免缓存304、404、50×等常见结果。
- 响应类型为 basic 或者 cors;即只缓存同源、或者正确地跨域结果;避免缓存错误的响应和不正确的跨域请求响应。
相关资料
[视频]PWA 入门√
[视频]PWA-3小时带你实现渐进式WebAPP√
深入浅出pwa√
Chrome PWA应用 安装和卸载√
Workbox Webpack插件√
PWA之 workbox 学习√
渐进式 Web 应用(PWA)
下一代 Web 应用模型 — Progressive Web App
PWA系列 – 分享PWA在阿里体系内的实践经验
PWA 介绍及快速上手搭建一个 PWA 应用
深入浅出 pwa
傻傻分不清的 Manifest
PWA 介绍及快速上手搭建一个 PWA 应用
十分钟让你完成一个可以安装到桌面的网页
饿了么的 PWA 升级实践
PWA 在饿了么的实践经验
现代化 Web 开发实践之 PWA
源码
开源
serve
http-server
vue-cli3 PWA
workbox
通用 PWA 构建器
基于 Webpack 模板的 Vue-Cli 的 PWA 模板
awesome-pwa 集合
使用VUE.JS构建实时PWA
关于Nuxt.js的零配置PWA解决方案
Vue店面 PWA
demo-progressive-web-app
项目不维护了 百度 基于vue 的 pwa 解决方案 Lavas
install_url
to use ShareThis. Please set it in _config.yml
.