美文网首页
pwa 学习与使用

pwa 学习与使用

作者: shengqz | 来源:发表于2018-02-02 22:25 被阅读135次

    最近,由于团队开发的需求,我对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新手教程:手把手教你制作自己的网页“小程序”

    相关文章

      网友评论

          本文标题:pwa 学习与使用

          本文链接:https://www.haomeiwen.com/subject/gcsezxtx.html