pwa 学习与使用

最近,由于团队开发的需求,我对Progressive Web Apps进行一定的研究。

背景

Progressive Web Apps(渐进式Web应用程序,简称PWA) 是 Google 提出的使用 Web 技术为网页提供如App使用体验的一种方案。
其主要特点如下:

  • 可靠 - 即使在不稳定的网络环境下,也能瞬间加载并展现
  • 体验 - 快速响应,并且有平滑的动画响应用户的操作
  • 粘性 - 像设备上的原生应用,具有沉浸式的用户体验,用户可以添加到桌面

可以 查看更详细的信息
总的来说,PWA能实现离线缓存,提高Web应用的响应速度,并能在移动端添加类似原生Native App的图标,以便开始使用。

使用

本次测试代码运用到Node来启动服务(请安装Nodejs)。Node启动服务部分参照 pwa-retrofit。步骤如下。

设计相应的manifest.json文件

manifest文件包含了一个网站的名字、主要颜色以及图标等数据。
第一种方法:我们可以在Favicon & App Icon Generator定义我们的图标。

预览图片

点击 Download the generated favicon 即可得到相应自定义图标信息和manifest.json文件。

第二种方法:登录Web App Manifest Generator,输入创建PWA各种信息。如果有不确定的,可不填。最后即可得到相应的信息。

manifest.json
{
  "name": "pwa-demo",
  "short_name": "demo",
  "lang": "zh-CN",
  "start_url": "/",
  "display": "standalone",
  "icons": [
    {
      "src": "/images/android-icon-48x48.png",
      "sizes": "48*48",
      "type": "image/png"
    }
  ]
}

准备相应的Html和Css

这里要注意Html相对的头部,这里可以用到上面自定义图标下载的信息。其它部分的Html和Css可以自身定制。

 <link rel="manifest" href="manifest.json">
 <meta name="mobile-web-app-capable" content="yes">
 <meta name="apple-mobile-web-app-capable" content="yes">
 <meta name="application-name" content="demo">
 <meta name="apple-mobile-web-app-title" content="demo">
 <meta name="msapplication-starturl" content="/">
 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 <link rel="icon" href="icon.png" type="image/png" />
 <link rel="stylesheet" href="/css/main.css">

添加Service Workers

一:在相应的Html引入main.js
main.js的重要内容

(function () {
    if (navigator.serviceWorker != null) {
        navigator.serviceWorker.register('/service-worker.js') // 注册相应的service-worker.js,路径根据项目自定义
            .then(function (registration) {
                console.log('Registered events at scope: ', registration.scope);
            });
    }
    if (!navigator.onLine) {
        // 离线时相应的操作...
    }
})()

二:添加关键的service-worker.js文件
首先我们需要了解Service Worker是什么。Service Worker,它实际上就是浏览器提供的JavaScript API,这组API的功能肯定是相当丰富了。其中最主要的功能有:对网页及其资源的离线缓存,对浏览器请求的拦截。
Service Worker的生命周期:
Service Worker拥有一个完全独立于Web页面的生命周期。
1、Service Worker在你的网页注册后生效,浏览器会启动安装(install)过程
2、安装过程,浏览器会缓存一些静态资源,所有静态资源被缓存成功,Service Worker就安装成功
3、Service Worker激活(activate),在这一阶段,你还可以升级一个Service Worker的版本。然后Service Worker会接管页面。
4、Service Worker接管界面后,它可能有两种状态:要么被终止以节省内存,要么会处理fetch和message事件。
以上就是Service Worker生命周期流程。可以查看更详细的信息

service-worker.js代码编写

const
    version = '1.1.0', 
    CACHE = version + '::pwa-sqz', // cache版本,可以迭代更换
    installFilesEssList = [   // 缓存的文件目录
        '/index.html',
        '/manifest.json',
        '/css/main.css',
        '/js/main.js',
        '/images/pwa-fonts.png',
        '/icon.png',
        '/offline.html'
    ]

安装阶段(install)

self.addEventListener('install', event => {
    console.log('install' + event)
    event.waitUntil(
        caches.open(CACHE)
            .then(cache => {
                cache.addAll(installFilesEssList)  //将目录文件进入缓存
            })
            .then(() => self.skipWaiting())
    )
})

激活阶段(activate)

self.addEventListener('activate', event => {
    console.log('activate' + event)
    event.waitUntil(
        caches.keys()
            .then(keylist => {
                return Promise.all(
                    keylist
                        .filter(key => key !== CACHE)
                        .map(key => caches.delete(key))  //删除旧的缓存
                )
            }).then(() => self.clients.claim()))
})

fetch阶段

self.addEventListener('fetch', event => {
    if (event.request && event.request.method !== 'GET') {
        return
    }
    event.respondWith(
        caches.open(CACHE)
            .then(cache => {
                return cache.match(event.request)
                    .then(response => {
                        if (response) {
                            console.log('cache fetch: ' + event.request.url)  //打印请求地址信息
                            return response
                        }
                        return fetch(event.request)  //fetch
                            .then(req => {
                                if (req.ok) cache.put(event.request, req.clone());
                                return req
                            })
                            .catch() //离线(offline)
                    })
            })
    )
})

缓存更新

service-worker.js代码中

const
    version = '1.1.0', 
    CACHE = version + '::pwa-sqz', // cache版本,可以迭代更换

修改version( 如 '1.1.1' )即可以更新

查看Demo

本次测试源代码github地址: pwa-demo。欢迎star。
源代码运行步骤

node ./server.js 8888

端口可以自定义(默认端口默认为 9998)

测试

Lighthouse是Chrome浏览器上的拓展程序,可以用于测试PWA,并提供相关的改善方案。在chrome应用商店安装完Lighthouse后,打开Lighthouse的Generate report进行测试。
页面效果:

home

about

contact

用Lighthouse测试效果:
测试效果

其中还能提示一些错误信息。
下面还有pwa一些推荐阅读:
Notification with Service Workers push events
PWA新手教程:手把手教你制作自己的网页“小程序”
下一代 Web 应用模型 —— Progressive Web App

参考资料
什么是 PWA
你的首个 Progressive Web App
下一代 Web 应用模型 —— Progressive Web App
pwa-retrofit
Service Worker 入门 - PWA 强依赖于 Service Worker
用人话来讲解一下 Service Worker 和 PWA
PWA新手教程:手把手教你制作自己的网页“小程序”

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容