PWA study notes (d)

Service Worker

Summary:

  1, Service Worker is one of PWA technical basis, out of the browser main thread of the features that make Web App offline caching possible,

    More background synchronization, such as push notification feature provides a guideline

  2, often speak of Service Worker refers Service Worker thread

  3, JavaScript execution file browser is running on a single thread, called the main thread, and Service Worker is an independent in

     Worker browser main thread, the main thread of the current browser is completely isolated and has its own independent execution context

  4, by  navigator.serviceWorker.register (file path) method will be able to register a Service Worker,

     New Service Worker from a thread on the basis of the current browser on the main thread

  5, Service Worker is not only independent of a worker thread main thread, and a can or offline environment running under worker threads

 

background:

  1, browser JavaScript is run on a single main thread on, at the same time can only do one thing.

     As the Web increasingly complex business, often there will be a lot of complicated operation process resource-intensive, time-consuming in JavaScript code logic.

     These processes lead to performance problems are more prominent in the Web App growing complexity of the process

  2, in order to solve the problem of unstable network connection Web, W3C early in proposed ApplicationCache offline caching mechanism to solve the problem,

     Practice is to specify a manifest file in an HTML page  manifest.appcache , specified in the manifest need for offline caching static resources,

     ApplicationCache can solve the problem can be accessed offline, but which also brought no small problem

  3, brought ApplicationCache mechanisms:

    (1) The definition of resources in all manifest.appcache file is loaded successfully, the resource files, along with file references manifest.appcahe

       HTML document a permanent off-line and moved to the cache . So if you want to cache only JS, CSS, pictures and other files without hope cache HTML documents

       To maintaining access to the latest content, it is a very big problem

    (2) According to the loading mechanism ApplicationCache, if only modify the content is cached resource file (do not modify the path or name of the resource file),

       The browser will get the resource file directly from the local offline cache . So every time you modify the resource file, should also be amended manifest.appcache file,

       To trigger the resource file to reload and cache , maintenance costs are too high

    (3) by a manifest.appcache configuration file to maintain a sophisticated caching strategy site is really a very difficult task,

       After all, simply relying configuration is very flexible in

    (4) for dynamic requests can not be processed

  4, based on double urgent need offline capabilities and offline caching mechanism Woker worker threads, through constant practice and development, the W3C proposed final

     Service Worker API can be run as an independent worker, combined with the persistent scheduling policy cache, the cache can solve the offline problem

 

Features:

  1, due to security considerations Service Worker must run in HTTPS under agreement

  2, has its own completely independent execution context . Once installed successfully on forever , unless the thread is a program to actively clear ,

     And when access is automatically activated when you close the automatic sleep , to reduce resource consumption

  3, fully asynchronous implementation, the interior of the asynchronous interface are implemented by Promise, and in the Service Worker can not directly operate the DOM ,

     For safety considerations and experience, UI rendering work must only be done in the main thread

  4, can intercept and proxy requests, request the return process content, persistent caching static resources to achieve the effect of offline access, and different ApplicationCache,

     Service Worker's all offline content developers fully controllable , and even can be controlled dynamically request, third party static resources

  5, offline and works in the background

注:可通过 'serviceWorker' in navigator 判断浏览器是否支持 Service Worker

 

作用域:

  1、Service Worker 作用域是一个 URL path 地址,指的是它能够控制的页面的范围

  2、“控制页面”是指 Service Worker 可以处理这些页面里面的资源请求和网络请求,

     然后通过它自身的调度机制构建离线缓存策略

  3、如果页面不在 Service Worker 的作用域范围内,Service Worker 就无法处理页面的任何资源或请求

     如:sw.js 在 /index/a/b 下,它只能控制 /index/a/b/*

注:类似于 Ajax 的跨域请求可以通过对请求的 Access-Control-Allow-Origin 设置,我们也可以通过服务器

    对 sw.js 这个文件的请求头进行设置,就能够突破作用域的限制,只需要在服务端对 sw.js 请求设置

    Service-Worker-Allowed 请求头为更大控制范围或者其他控制范围的 scope 即可。如:Service-Worker-Allowed: /a/

  4、作用域污染:多个 Service Worker 控制同一个页面

注:通过进行手动 “unregister” 来清除掉污染的 Service Worker或借助 navigator.serviceWorker.getRegistrations()

    方法将污染的 Service Worker 先注销掉,然后在注册自己的所在作用域的 Service Worker

 

生命周期:

  1、在主线程成功注册 Service Worker 之后,开始下载并解析执行 Service Worker 文件,

     执行过程中开始安装 Service Worker,在此过程中会触发 worker 线程的 install 事件

  2、如果 install 事件回调成功执行(在 install 回调中通常会做一些缓存读写的工作,可能会存在失败的情况),

     则开始激活 Service Worker,在此过程中会触发 worker 线程的 activate 事件,如果 install 事件回调执行失败

     则生命周期进入 Error 终结状态,终止生命周期

  3、完成激活之后,Service Worker 就能够控制作用域下的页面的资源请求,可以监听 fetch 事件

  4、如果在激活后 Service Worker 被 unregister 或者有新的 Service Worker 版本更新

     则当前 Service Worker 生命周期完结,进入 Terminated 终结状态

  5、工作流程:

    (1)Service Worker 文件只在首次注册的时候执行了一次

    (2)安装、激活流程也只是在首次执行 Service Worker 文件的时候进行了一次

    (3)首次注册成功的 Service Worker 没能拦截当前页面的请求

    (4)非首次注册的 Service Worker 可以控制当前的页面并能拦截请求

注:首次注册没能拦截请求是因为,Service Worker 的注册是一个异步的过程,在激活完成后当前页面的请求

    都已经发送完成,因为时机太晚,此时是拦截不到任何请求的,只能等待下次访问再进行

  6、waitUntil 机制:

    (1)由于 Service Worker 生命周期异步触发的特性,当 install 回调中的逻辑报错了,并不会影响 Service Worker

       的生命周期继续向后推进,即后面如果没错的话 active 事件仍会被触发

    (2)Service Worker 事件回调的参数是一个 ExtendableEvent 对象,在 Service Worker 中需要使用

       ExtendableEvent.waitUntil() 方法来保证生命周期的执行顺序,该方法接收一个 Promise 参数

// sw.js
console.log('service worker 注册成功')

self.addEventListener('install', event => {
  // 引入 event.waitUntil 方法
  event.waitUntil(new Promise((resolve, reject) => {
    // 模拟 promise 返回错误结果的情况
    reject('安装出错')
    // resolve('安装成功')
  }))
})

self.addEventListener('activate', () => {
  // 激活回调的逻辑处理
  console.log('service worker 激活成功')
})

self.addEventListener('fetch', event => {
  console.log('service worker 抓取请求成功: ' + event.request.url)
})

    (3)在 install 事件回调被调用时,waitUntil 把即将被激活的 worker 线程状态延迟为 installing 状态

       直到传递的 Promise 被成功地 resolve,确保:Service Worker 工作线程在所有依赖的

       核心 cache 被缓存之前都不会被安装

    (4)当 ExtendableEvent.waitUntil()运行时,如果 Promise 是 resolved,任何事情都不会发生

       如果 Promise 是 rejected,installing 或者 activating 的状态会被设置为 redundant

注:如果在 ExtendableEvent 处理程序之外调用 waitUntil(),浏览器会抛出一个InvalidStateError 错误。

    如果多个调用将会堆叠,所产生的所有 promise 将被添加到延长生命周期的 promise 等待执行完成

  7、终端:

    (1)在手机端或者 PC 端浏览器,每新打开一个已经激活了 Service Worker 的页面,那 Service Worker 所控制的终端就

       新增一个,每关闭一个包含已经激活了 Service Worker 页面的时候(不包含手机端浏览器进入后台运行的情况),

       则 Service Worker 所控制的终端就减少一个

    (2)当所有的终端共用一个 worker 工作线程时,在 worker 线程中执行 console.log()等操作会作用到所有的终端

    (3)self.clients.claim()使激活 Service Worker 之后马上控制所有终端

 

更新原理:

  1、当浏览器监测到新的 Service Worker 更新之后,会重新进行注册、安装

  2、当检测到当前的页面被激活态的 Service Worker 控制着的话,会进入 waiting 状态

  3、waiting 后有两种选择:

    (1)通过 skipWaiting 跳过 waiting 状态

    (2)在所有终端保持 waiting 状态,直到 Service Worker 对所有终端失去控制(关闭所有终端的时候)

  4、Service Worker 在全局提供了一个 skipWaiting() 方法,skipWaiting() 在 waiting 期间调用

     还是在之前调用并没有什么不同

  5、手动更新:

    (1)当刷新页面重新执行 register 方法时,浏览器检测到 Service Worker 文件更新则触发该文件更新

    (2)如果站点在浏览器后台长时间没有被刷新,则浏览器将自动检查更新,通常是每隔 24 小时检查一次

    (3)手动触发更新代码

// 1 小时重新加载一次
navigator.serviceWorker.register('/sw.js')
  .then(reg => {
    setInterval(() => {
      reg.update()
    }, 60 * 60 * 1000)
  })

  6、通过 update on reload 功能,开发者可以做到以下几点:

    (1)重新提取 Service Worker

    (2)即使字节完全相同,也将其作为新版本安装,这表示运行 install 事件并更新缓存

    (3)跳过 waiting 阶段,直接激活新 Service Worker

    (4)浏览页面,每次浏览时(包括刷新)都将进行更新,无需重新加载两次或关闭标签

 

调试:

  1、关注点:

    (1)Service Worker 文件 JavaScript 代码是否有报错

    (2)Service Worker 能否顺利安装、激活或者更新

    (3)在不同机型上的兼容性是不是有问题

    (4)不同类型资源和请求的缓存策略的验证

  2、debug 环境下的开发跳过等待状态:使用 skipWaiting

  3、借助 Chrome Devtool 进行调试:

    (1)Offline:复选框可将 DevTools 切换至离线模式,等同于 Network 窗格中的离线模式

    (2)Update on reload:复选框可强制 Service Worker 线程在每次页面加载时更新

    (3)Bypass for network:复选框可绕过 Service Worker 线程并强制浏览器转至网络寻找请求的资源

    (4)Update:按钮可对指定的 Service Worker 线程执行一次性更新

    (5)Push:按钮可在没有负载的情况下模拟推送通知

    (6)Sync:按钮可模拟后台同步事件

    (7)Unregister:按钮可注销指定的 Service Worker 线程

    (8)Source:告诉当前正在运行的 Service Worker 线程的安装时间,链接是 Service Worker 线程源文件的名称

       点击链接会将定向并跳转至 Service Worker 线程来源

    (9)Status:告诉 Service Worker 线程的状态

    (10)Clients:告诉 Service Worker 线程作用域的原点

  4、查看缓存:Cache Storage 选项卡提供了一个已使用(Service Worker 线程)Cache API 缓存的只读资源列表

  5、网络跟踪:

    (1)经过 Service Worker 的 fetch 请求 Chrome 都会在 Chrome DevTools Network 标签页里标注出来

    (2)来自 Service Worker 的内容会在 Size 字段中标注为 from ServiceWorker

    (3)Service Worker 发出的请求会在 Name 字段中添加 ⚙ 图标

  6、真机调试:

    (1)Android

      ①准备:

        ·PC 上已安装 Chrome 32 或更高版本

        ·PC 上已安装 USB 驱动程序(如果使用 Windows),确保设备管理器报告正确的 USB 驱动程序

        ·一根可以将 Android 设备连接至开发计算机的 USB 线

        ·一台 Android 4.0 或更高版本的 Android 设备

      ②步骤:

        ·将 Android 设备通过 USB 线与 PC 连接

        ·在 Android 设备上进行一些设置,选择 “设置 > 开发者选项 > 开启 USB 调试”

        ·在 PC 上打开 Chrome,使用一个 Google 帐户登录到 Chrome

         (远程调试在隐身模式或访客模式下无法运行)

        ·在 PC 的 Chrome 浏览器地址栏输入 chrome://inspect

        ·在 Remote Target 下找到对应的 Android 设备

        ·点击远程设备链接进入 Chrome Devtools

    (2)iOS

      ①准备:

        ·一台 Mac 电脑

        ·一个 icloud 账号

        ·一个 Apple 的移动设备(iPhone)

        ·用 iCloud 账号登陆 Mac 和 iPhone

        ·对 iPhone 进行设置:设置 > Apple ID 用户中心入口 > iCloud > 打开 Safari

        ·对 iPhone 进行设置:设置 > Safari浏览器 > 高级 > 打开 Web Inspector

        ·对 Mac 进行设置:系统偏好设置 > iCloud > 勾上 Safari

        ·对 Mac 进行设置:打开 Safari > Safari 菜单 > 偏好设置 > 高级 > 勾选“在菜单栏中显示开发菜单”

        (这时候 Safari 的系统菜单栏多了一个 开发 标签)

     ②步骤:

       ·用 USB 线连接 iPhone 和 Mac

       ·在 iPhone 上打开 PWA 站点

       ·打开 Mac 上 Safari 菜单栏的 开发 标签,就可以点击进 我的 iPhone

       ·接下来会发现 我的 iPhone 子菜单里有在 iphone 上打开的 PWA 站点,

         这时候就可以用 Safari 的 Devtools 进行调试

Guess you like

Origin www.cnblogs.com/lemonyam/p/11939275.html