PWA学习

作者: lmmy123 | 来源:发表于2019-02-15 20:10 被阅读12次
    PWA全称Progressive Web App,即渐进式WEB应用。

    一个 PWA 应用首先是一个网页, 可以通过 Web 技术编写出一个网页应用. 随后添加上 App Manifest 和 Service Worker 来实现 PWA 的安装和离线等功能
    解决了哪些问题?

    • 可以添加至主屏幕,点击主屏幕图标可以实现启动动画以及隐藏地址栏
    • 实现离线缓存功能,即使用户手机没有网络,依然可以使用一些离线功能
    • 实现了消息推送
      这些特性使得web应用渐进式接近原生app
    PWA的实现
    Manifest实现添加至主屏幕

    index.html

    <head>
      <title>Minimal PWA</title>
      <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">
      <link rel="icon" href="/e.png" type="image/png" />
    </head>
    

    manifest.json

    {
      "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"
      }
      ]
    }
    
    service worker实现离线缓存

    什么是service worker?
    Service Worker 是 Chrome 团队提出和力推的一个 WEB API,用于给 web 应用提供高级的可持续的后台处理能力。

    image.png
    service Workers 就像介于服务器和网页之间的拦截器,能够拦截进出的HTTP 请求,从而完全控制你的网站
    HTTP缓存与service worker缓存
    Service Workers 的强大在于它们拦截 HTTP 请求的能力
    进入任何传入的 HTTP 请求,并决定想要如何响应。在你的 Service Worker 中,可以编写逻辑来决定想要缓存的资源,以及需要满足什么条件和资源需要缓存多久。一切尽归你掌控!
    **实现离线缓存
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>Hello Caching World!</title>
      </head>
      <body>
        <!-- Image -->
        <img src="/images/hello.png" />                 
        <!-- JavaScript -->
        <script async src="/js/script.js"></script>     
        <script>
          // 注册 service worker
          if ('serviceWorker' in navigator) {           
            navigator.serviceWorker.register('/service-worker.js', {scope: '/'}).then(function (registration) {
              // 注册成功
              console.log('ServiceWorker registration successful with scope: ', registration.scope);
            }).catch(function (err) {                   
              // 注册失败 :(
              console.log('ServiceWorker registration failed: ', err);
            });
          }
        </script>
      </body>
    </html>
    

    注:Service Worker 的注册路径决定了其 scope 默认作用页面的范围。
    如果 service-worker.js 是在 /sw/ 页面路径下,这使得该 Service Worker 默认只会收到 页面/sw/ 路径下的 fetch 事件。
    如果存放在网站的根路径下,则将会收到该网站的所有 fetch 事件。
    如果希望改变它的作用域,可在第二个参数设置 scope 范围。示例中将其改为了根目录,即对整个站点生效。
    service-worker.js

    var cacheName = 'helloWorld';     // 缓存的名称  
    // install 事件,它发生在浏览器安装并注册 Service Worker 时        
    self.addEventListener('install', event => { 
    /* event.waitUtil 用于在安装成功之前执行一些预装逻辑
     但是建议只做一些轻量级和非常重要资源的缓存,减少安装失败的概率
     安装成功后 ServiceWorker 状态会从 installing 变为 installed */
      event.waitUntil(
        caches.open(cacheName)                  
        .then(cache => cache.addAll([    // 如果所有的文件都成功缓存了,便会安装完成。如果任何文件下载失败了,那么安装过程也会随之失败。        
          '/js/script.js',
          '/images/hello.png'
        ]))
      );
    });
      
    /**
    为 fetch 事件添加一个事件监听器。接下来,使用 caches.match() 函数来检查传入的请求 URL 是否匹配当前缓存中存在的任何内容。如果存在的话,返回缓存的资源。
    如果资源并不存在于缓存当中,通过网络来获取资源,并将获取到的资源添加到缓存中。
    */
    self.addEventListener('fetch', function (event) {
      event.respondWith(
        caches.match(event.request)                  
        .then(function (response) {
          if (response) {                            
            return response;                         
          }
          var requestToCache = event.request.clone();  //          
          return fetch(requestToCache).then(                   
            function (response) {
              if (!response || response.status !== 200) {      
                return response;
              }
              var responseToCache = response.clone();          
              caches.open(cacheName)                           
                .then(function (cache) {
                  cache.put(requestToCache, responseToCache);  
                });
              return response;             
        })
      );
    });
    
    service workers 技术实践项目:https://github.com/zhangxinxu/https-demo/blob/master/cache

    文章参考:https://segmentfault.com/a/1190000012353473?utm_source=tag-newest

    相关文章

      网友评论

          本文标题:PWA学习

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