• PWA入门 -- H5时代原生APP


    本文是一个PWA的入门教程,也算是一个introduction(导读),不会太深入
    主要聊聊三个重点: PWA的本质,构成PWA的两个文件,PWA APP如何更新

    PWA的本质

    Q: 网站和原生app在存储上的本质区别是什么?
    A: 网站中使用的素材都是通过请求实时获取的, app中使用的素材都是本机中存储的。在离线或者素材过大的情况下,前者每次访问都要加载,加载过慢的缺点就暴露了出来。离线使用体验永远大于在线使用体验

    有了这个前置知识之后,补充一个事实: chrome在版本43, 2015年5月的时候提供了chache API
    而cache API就是PWA的魔法: 通过预先下载素材缓存到cache里,下次打开就不用经过网络请求,实现离线的效果

    个人感觉这样解释应该很清晰了,所以下面进入实际操作环节:

    两个文件

    从表面上看,要将一个网站转成PWA网站,只需要添加两个文件: manifest.json和service-worker.js
    前者是对APP的说明,后者是我们进行cache操作的地方

    manifest.json

    在这个配置文件里我们可以定义:

    1. name: APP的名称
    2. short_name: 被添加到桌面(相当于安装)后, app图标下面的名称
    3. start_url: 打开应用时所处URL
    4. display: 指定成standlone就能显示的跟原生APP一样(没有浏览器导航栏之类的东西)

    其他还有背景颜色和图标之类的,都是些简单的属性在MDN上查一下就完事了: https://developer.mozilla.org/en-US/docs/Web/Manifest

    service-worker.js(简称sw)

    要用sw,首先要在index.html里对sw进行注册

    navigator.serviceWorker.register('/sw.js')
          .then(reg => console.log('service worker registered'))
          .catch(err => console.log('service worker not registered', err));
    

    sw相当于一个安装器+拦截器,简单说下这个安装过程是怎么实现的: 每次执行navigator.serviceWorker.register('/sw.js')都会重新下载sw.js这个文件,就像每次打开网络游戏都要先检查更新登陆器一样, 然后登陆器会告诉我们是不是要下载安装补丁包。如果新下载的sw.js跟之前稍微有点不一样,我们的网站都会被认为是一个新版本,然后重新触发install事件(在sw.js里面监听), 反之如果文件完全一样就不会触发install事件. 就像更新结束之后网游会要求用户重启游戏一样, install结束之后,我们进入一个等待状态,只有用户重新打开网站,我们才会进入激活状态触发activate事件(和install事件一样activate事件一个版本只触发一次).

    请仔细阅读上面这个描述,我已经尽可能用简单易懂的方式去描述了。上面提到的两个事件install和activate是最重要的,前者我们通常新建一个cache,然后预加载素材。用户重启网站后,在activate事件里我们通常删除上个版本的cache。

    下面是无聊的代码(占了整个sw文件的三分之二),就是做了上述的两件事情, 不想看就跳过吧

    const staticCacheName = 'site-static-v1';
    const assets = [
      '/',
      '/index.html?v=4',
      '/assets/js/ui.js',
      '/assets/css/main.css',
      '/assets/images/background-home.jpg',
      'https://fonts.googleapis.com/css?family=Lato:300,400,700',
    ];
    // install event
    self.addEventListener('install', evt => {
      evt.waitUntil(
        caches.open(staticCacheName).then((cache) => {
          console.log('caching shell assets');
          cache.addAll(assets);
        })
      );
    });
    // activate event
    self.addEventListener('activate', evt => {
      evt.waitUntil(
        caches.keys().then(keys => {
          return Promise.all(keys
            .filter(key => key !== staticCacheName)
            .map(key => caches.delete(key))
          );
        })
      );
    });
      
    

    在sw里,我们主要做的事情有两件:

    1. 管理cache(增删查改)
    2. 拦截网络请求, 从而实现像动态cache之类的骚操作

    拦截网络请求就是剩下的三分之一代码, 针对一个请求我们先检查cache里面有没有,如果有就直接返回,没有就继续请求:

    self.addEventListener('fetch', evt => {
      evt.respondWith(
        caches.match(evt.request).then(cacheRes => {
          return cacheRes || fetch(evt.request);
        })
      );
    });
    

    上面就是整个sw的代码和工作原理

    用谷歌教程上的话来说,sw的生命周期是pwa最大的难点, 全部的工作原理我都在上面说明了, 如果看明白了那你就是掌握了pwa最难的部分,接下来我再总结一下(三个状态):

    1. 预加载素材时的安装中状态installing
    2. install完之后, 新的sw + chache没有立即生效,而是进入等待用户重新打开网站的waiting状态
    3. 用户重新打开网站之后,进入激活状态activate

    PWA APP如何更新

    从上面sw的工作原理部分可以得知,sw.js是每次打开网站都会重新加载的!
    所以想要更新网站很简单,只要更改sw.js(比如加上一行新的素材路径), 然后在install事件里新开一个cache,然后在activate事件里删除旧版本cache就OK了

    比如上面的代码, activate事件里已经做了删除旧cache的操作(如果cache和当前版本cache名不一样就删掉),所以只要更改staticCacheName就可以了

  • 相关阅读:
    node 安装及环境配置
    vue 多级嵌套组件的通信方式
    uniapp 直播(推流)
    css3 弹出层居中(防止穿透滚动)
    uniapp App打开没有关掉后台,去查看其它东西一段时候回来后,页面会变空白
    uniapp 根据给定的经纬度、地址address,调取地图导航
    208道面试题,答案
    十分钟了解单元测试
    异常处理的一些见解
    MySQL(MariaDB)常用DOM命令
  • 原文地址:https://www.cnblogs.com/uturobako/p/pwa-basic.html
Copyright © 2020-2023  润新知