zoukankan      html  css  js  c++  java
  • PWA 学习笔记(五)

    离线与缓存

    资源请求的拦截代理:

      1、资源请求的判断:

        (1)fetch 事件会拦截页面上所有的网络资源请求,但我们通常只对部分资源请求进行处理,

           其余的请求会继续走浏览器默认的资源请求流程

        (2)fetch 事件回调参数的 event.request 属性描述了当前被拦截的资源请求,可以通过它来进行判断分类。

           event.request 是 Request 对象的实例,包含了资源请求的 URL、请求模式、请求头等全部信息

        (3)一般情况下,资源请求的判断可以通过对 event.request.url 进行匹配来实现

    // 全等匹配
    if (event.request.url === 'http://127.0.0.1:8080/data.txt') {
      // 匹配成功
    }
    
    // 正则匹配
    if (//data.txt/.test(event.request.url)) {
      // 匹配成功
    }
    
    // 借助 URL 进行匹配
    let url = new URL(event.request.url)
    if (
      url.hostname === '127.0.0.1' &&
      url.port === '8080' &&
      url.pathname === '/data.txt'
    ) {
      // 匹配成功
    }

    注:正则表达式可参考我之前的随笔 https://www.cnblogs.com/lemonyam/p/10649030.html

      2、资源请求的响应:

        (1)fetch 事件回调参数的方法 event.respondWith(r) 可以指定资源请求的响应结果

        (2)respondWith(r) 方法的参数 r 可以是一个 Response 对象实例,也可以是一个 Promise 对象,这个 Promise 对象

           在异步执行完成的时候同样需要 resolve 返回一个 Response 对象实例作为请求的响应结果

    // 直接返回 Response 对象
    event.respondWith(new Response('Hello World!'))
    
    // 等待 1 秒钟之后异步返回 Response 对象
    event.respondWith(new Promise(resolve => {
      setTimeout(() => {
        resolve(new Response('Hello World!'))
      }, 1000)
    }))

      3、异步资源请求响应:

        (1)event.respondWith 方法与 install、activate 事件回调参数中的 event.waitUntil 类似,

           起到了扩展延长 fetch 事件生命周期的作用

        (2)在 fetch 事件回调同步执行完毕之前如果没有调用 event.respondWith(r) 指定资源响应结果,

           那么就会进入浏览器默认的资源请求流程当中

    // 错误用法
    self.addEventListener('fetch', event => {
      if (event.request.url === 'http://127.0.0.1:8080/data.txt') {
        setTimeout(() => {
          event.respondWith(new Response('Hello World!'))
        }, 1000)
      }
    })
    
    // 正确用法
    
    // 等待 1 秒钟之后异步返回 Response 对象
    event.respondWith(new Promise(resolve => {
      setTimeout(() => {
        resolve(new Response('Hello World!'))
      }, 1000)
    }))

      4、资源请求响应的错误处理:

        (1)当使用了 event.respondWith 指定资源响应之后,无论是以同步还是异步的方式,最终都需要返回 Response 对象

        (2)在调用 event.respondWith 的时候,需要主动捕获并处理错误、异常返回结果

      5、资源请求与响应操作的管理:

        在 fetch 事件回调当中主要进行着资源请求匹配和响应结果返回的操作,可以把这个过程当做一个路由分发的问题,

        因此我们可以封装一个 Router 类来实现对路由的匹配规则和操作分发的统一管理

    本地存储管理:

      1、因为基于性能上的考虑,Service Worker 在设计标准时就要求了任何耗时操作必须异步实现这也导致了在

         Service Worker 作用域下能够使,目前只有 Cache API 和 IndexedDB因为目前只有二者在功能实现上全部

         采用了异步形式,而其他诸如 localStorage 属于同步方法,因此无法在 Service Worker 中使用

      2、Cache API 与 IndexedDB 的应用场景:

        (1)Cache API 适用于请求响应的本地存储:为资源请求与响应的存储量身定做的,它采用了键值对的数据模型

           存储格式,以请求对象为键、响应对象为值,正好对应了发起网络资源请求时请求与响应一一对应的关系

        (2)IndexedDB 是一种非关系型数据库,它的存储对象主要是数据,比如数字、字符串、Plain Objects、Array 等,

           以及少量特殊对象比如 Date、RegExp 等等,对于 Request、Response 这些是无法直接被 IndexedDB 存储的

        (3)Cache API 和 IndexedDB 在功能上是互补的。在设计本地资源缓存方案时通常以 Cache API 为主,

           但在一些复杂的场景下,Cache API 这种请求与响应一一对应的形式存在着局限性,因此需要结合上功能上更为

           灵活的 IndexedDB,通过 IndexedDB 存取一些关键的数据信息,辅助 Cache API 进行资源管理

      3、缓存注意项:

        (1)本地存储空间是有限的:浏览器提供了 StorageEstimate API 去查询当前缓存空间的使用情况

    navigator.storage.estimate()
        .then(estimate => {
            // 设备为当前域名所分配的存储空间总大小
            console.log(estimate.quota)
            // 当前域名已经使用的存储空间大小
            console.log(estimate.usage)
        })

        (2)资源的存取过程可能会失败:应该随时做好存取失败时的异常捕获与降级方案,确保程序运行时不会出错

        (3)存储的资源可能会过期:要及时做好资源的更新和旧资源的清理工作

  • 相关阅读:
    STL中队列queue的常见用法
    牛客网剑指offer第17题——树的子结构
    《剑指offer》网络大神所有习题题解
    牛客网剑指offer第4题——重建二叉树
    牛客网剑指offer第56题——删除链表中重复的节点
    图像处理中的求导问题
    hash_set和hash_map
    hashtable初步——一文初探哈希表
    数据结构-链表的那些事(下)(二)
    数据结构-链表的那些事(上)(一)
  • 原文地址:https://www.cnblogs.com/lemonyam/p/11941921.html
Copyright © 2011-2022 走看看