• 重识 PWA 进阶到 workbox3


    看到PWA,似曾相识,但又感觉很模糊,于是乎,又重新翻阅文档,学习了一遍,顺便把相关知识学习了一下,比如service worker,workbox3

    PWA 概念:

    全称:Progressive Web APP, 渐进式 Web 应用。

    实际上是通过 Web 技术编写出的一个网页应用,加上App ManifestService Worker来实现PWA的安装和离线缓存等功能。

    解决了哪些问题?

    • 可以添加至主屏幕,点击主屏幕图标可以实现启动动画及隐藏地址栏
    • 实现离线缓存功能
    • 实现了消息推送

    PWA 的实现-Manifest 实现添加至主屏幕

    首先在index.htmlhead中引入manifest.json文件,尽可能早的引入

    <head>
        ...
        <meta name="viewport" content="width=device-width, user-scalable=no" />
        <link rel="manifest" href="manifest.json">
        <link rel="stylesheet" type="text/css" href="main.css">
        ...
    </head>
    

    然后编写manifest.json文件,参考文档:https://developer.mozilla.org/zh-CN/docs/Web/Manifest

    {
      "name": "Minimal PWA", // 必填 显示的插件名称
      "short_name": "PWA Demo", // 可选  在APP launcher和新的tab页显示,如果没有设置,则使用name
      "description": "The app that helps you understand PWA", //用于描述应用
      "display": "standalone", // 定义开发人员对Web应用程序的首选显示模式。standalone模式会有单独的
      "start_url": "/", // 应用启动时的url
      "theme_color": "#313131", // 桌面图标的背景色
      "background_color": "#313131", // 为web应用程序预定义的背景颜色。在启动web应用程序和加载应用程序的内容之间创建了一个平滑的过渡。
      "icons": [ // 桌面图标,是一个数组
        {
        "src": "icon/lowres.webp",
        "sizes": "48x48",  // 以空格分隔的图片尺寸
        "type": "image/webp"  // 帮助userAgent快速排除不支持的类型
      },
      {
        "src": "icon/lowres",
        "sizes": "48x48"
      },
      {
        "src": "icon/hd_hi.ico",
        "sizes": "72x72 96x96 128x128 256x256"
      },
      {
        "src": "icon/hd_hi.svg",
        "sizes": "72x72"
      }
      ]
    }
    

    PWA的实现-Service Worker 实现离线缓存

    Service worker,是 Chrome 团队提出和力推的一个 WEB API,就像介于服务器和网页之间的拦截器,能够拦截进出的http请求,从而完全控制你的网站。

    最主要的特点:

    • 在页面中注册并安装成功后,运行于浏览器后台,不受页面刷新的影响,可以监听和拦截作用域范围内所有页面的 HTTP 请求。
    • 网站必须使用 HTTPS,处于安全考虑,避免被攻击。除了使用贝蒂开发环境调试。
    • 运行于浏览器后台,可以控制打开的作用域范围下所有的页面请求
    • 单独的作用域范围,单独的运行环境和执行线程
    • 不能操作页面 DOM ,但是可以通过事件机制来处理
    • 事件驱动型服务线程

    浏览器支持情况:

    生命周期

    解析成功(parsed)、正在安装(installing)、安装整个(installed)、正在激活(activating)、激活成功(activated)、废弃(redundant)

    若 installing 事件失败或 activeing 事件失败,service worker 都会被废弃。

    实现离线缓存

    首先在index.html中注册sw.js

    <script async src="/js/script.js"></script>     
    <script>
      // 注册 service worker
      if ('serviceWorker' in navigator) {           
        navigator.serviceWorker.register('/sw.js', {scope: '/'}).then(function (registration) {
          // 注册成功
          console.log('ServiceWorker registration successful with scope: ', registration.scope);
        }).catch(function (err) {                   
          // 注册失败 :(
          console.log('ServiceWorker registration failed: ', err);
        });
      }
    </script>
    

    编写sw.js

    var cacheStorageKey = 'cachesName'
    var cacheList = [
      // 注册成功后要立即缓存的资源列表
    ]
    
    // 当浏览器解析完sw文件时触发install事件
    self.addEventListener('install', function(e) {
      // install事件中一般会将cacheList中要换存的内容通过addAll方法,拉一遍放入caches中
      e.waitUntil(
        caches.open(cacheStorageKey).then(function(cache) {
          return cache.addAll(cacheList)
        })
      )
    })
    
    // 激活时触发activate事件
    self.addEventListener('activate', function(e) {
      // active事件中通常做一些过期资源释放的工作,匹配到就从caches中删除
      var cacheDeletePromises = caches.keys().then(cacheNames => {
        return Promise.all(cacheNames.map(name => {
          if (name !== cacheStorageKey) {
            return caches.delete(name);
          } else {
            return Promise.resolve();
          }
        }));
      });
    
      e.waitUntil(
        Promise.all([cacheDeletePromises])
      )
    })
    
    self.addEventListener('fetch', function(e) {
      // 在此编写缓存策略, 需要根据不同文件的扩展名把不同的资源通过不同的策略缓存在caches中,各种css,js,html,图片,都需要单独搞一套缓存策略
    
      e.respondWith(
        // 可以通过匹配缓存中的资源返回
        caches.match(e.request)
        // 也可以从远端拉取
        fetch(e.request.url)
        // 也可以自己造
        new Response('自己造')
        // 也可以通过吧fetch拿到的响应通过caches.put方法放进chches
      )
    })
    

    workbox3

    workbox3,Google官方 PWA 框架,解决的就是 Service Worker 编写太过复杂的问题。

    // 首先引入workbox框架
    importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.3.0/workbox-sw.js');
    
    workbox.precaching([
      // 注册成功后要立即缓存的资源列表
    ])
    
    // 缓存策略: networkFirst、cacheFirst、staleWhileRevalidate
    workbox.routing.registerRoute(
      new RegExp(''.*.html'),
      workbox.strategies.networkFirst()
    );
    
    workbox.routing.registerRoute(
      new RegExp('.*.(?:js|css)'),
      workbox.strategies.cacheFirst()
    );
    
    workbox.routing.registerRoute(
      new RegExp('https://your.cdn.com/'),
      workbox.strategies.staleWhileRevalidate()
    );
    

    生成缓存策略,可以采用workbox-build npm 包或者workbox-webpack-plugin方式自动生成。

    缓存策略:

    • stateWhileRevalidate:当请求的路由有对应的 Cache 缓存结果就直接返回,在返回 Cache 缓存结果的同时会在后台发起网络请求拿到请求结果并更新 Cache 缓存,如果本来就没有 Cache 缓存的话,直接就发起网络请求并返回结果,这对用户来说是一种非常安全的策略
    • networkFirst:当请求路由是被匹配的,就采用网络优先的策略,也就是优先尝试拿到网络请求的返回结果,如果拿到网络请求的结果,就将结果返回给客户端并且写入 Cache 缓存,如果网络请求失败,那最后被缓存的 Cache 缓存结果就会被返回到客户端,这种策略一般适用于返回结果不太固定或对实时性有要求的请求,为网络请求失败进行兜底。
    • cacheFirst:当匹配到请求之后直接从 Cache 缓存中取得结果,如果 Cache 缓存中没有结果,那就会发起网络请求,拿到网络请求结果并将结果更新至 Cache 缓存,并将结果返回给客户端。这种策略比较适合结果不怎么变动且对实时性要求不高的请求
    • networkOnly:强制使用正常的网络请求,并将结果返回给客户端,这种策略比较适合对实时性要求非常高的请求。
    • cacheOnly:直接使用 Cache 缓存的结果,并将结果返回给客户端,这种策略比较适合一上线就不会变的静态资源请求。
    • 如果以上策略都不满足需求,还可以自定义策略

    参考文档

    • 讲讲PWA
      • 背景
      • What's PWA?
      • PWA的实现
        • Manifest实现添加至主屏幕
        • service worker实现离线缓存
        • serice worker实现消息推送
      • 总结:PWA的优势和存在的问题
      • 参考文档
    • Vue笔记九:pwa技术在vue的使用(workbox/sw-precache)
      • 历史背景
      • sw-precache 和 workbox
      • 缓存机制
      • 安全性
    • Workbox 3.0 – Web 站点轻松做到离线可访问
      • 概述
      • 用法
      • precache (预缓存)静态文件
      • 处理/和/index.html
      • 忽略请求参数
      • 生成预缓存列表
        • workbox 命令行
        • workbox-build npm 包
        • workbox-webpack-plugin
      • 路由请求缓存
        • 字符串方式
        • 正则表达式fangs
        • 回调函数方式
      • 路由请求缓存策略
        • state while revalidate
        • network first
        • cache first
        • network only
        • cache only
      • 自定义策略
      • 第三方请求的缓存
      • workbox 配置
        • 配置缓存名称
        • 指定 development 环境
        • 配置日志 level: debug、log、warning、error
      • workbox 插件
      • 自定义插件
      • webpack 中使用 workbox 实现 PWA
    • Workbox3 - ServiceWorker可以如此简单
      • 科普ServiceWorker
      • 一个完整的ServiceWorker
      • workbox3
      • 经验之谈
    • Service Worker 生命周期
      • 解析成功(parsed)、正在安装(installing)、安装整个(installed)、正在激活(activating)、激活成功(activated)、废弃(redundant)
  • 相关阅读:
    Sencha Touch 框架快速入门系列
    dotTrace 使用说明
    CQRS架构中同步服务的一种实现方式
    C#中循环结构的效率问题
    面向领域驱动架构的查询实现方式
    最佳 jQuery
    DWZ&MVC的探索系列——Demo演示效果
    在Windows Azure中实现和调试一个WCF服务(上)
    现代软件工程开发体验:结对编程
    结对编程是什么?
  • 原文地址:https://www.cnblogs.com/EnSnail/p/9824198.html
Copyright © 2020-2023  润新知