Service Worker MDN英文笔记
前言: 以前学习基础知识的时候总看别人写的入门文章,但有时候还是一脸懵逼,直到自己用心阅读了MDN的英文文档才对基础知识的一些理论有了更深的理解,所以我在边阅读文档的时候边记录下帮助比较大的,也方便大家简洁学习。建议英文不好的同学可以先看我之前学的中文版基础知识再来学习这篇英文整理。Service Worker基础知识整理
Service worker concepts
Service workers essentially act as proxy servers that sit between web applications, the browser, and the network (when available).
A service worker is an event-driven worker registered against an origin and a path.A service worker is run in a worker context: it therefore has no DOM access, and runs on a different thread to the main JavaScript that powers your app, so it is not blocking. It is designed to be fully async; as a consequence, APIs such as synchronous XHR and localStorage can't be used inside a service worker.
Service worker register
ExamplesSection The examples described here should be taken together to get a better understanding of how service workers scope applies to a page.
The following example uses the default value of scope (by omitting it). The service worker in this case will controlexample.com/index.html as well as pages underneath it, likeexample.com/product/description.html.
if ('serviceWorker' in navigator) {
  // Register a service worker hosted at the root of the
  // site using the default scope.
  navigator.serviceWorker.register('/sw.js').then(function(registration) {
    console.log('Service worker registration succeeded:', registration);
  }, /*catch*/ function(error) {
    console.log('Service worker registration failed:', error);
  });
} else {
  console.log('Service workers are not supported.');
}
 note this is the file's URL relative to the origin, not the JS file that references it.
A single service worker can control many pages. Each time a page within your scope is loaded, the service worker is installed against that page and operates on it. Bear in mind therefore that you need to be careful with global variables in the service worker script: each page doesn’t get its own unique worker.

The following code, if included in a page at the root of a site, would apply to exactly the same pages as the example above. Remember the scope, when included, uses the page's location as its base. Alternatively, if this code were included in a page atexample.com/product/description.html, the scope of './' would mean that the service worker only applies to resources underexample.com/product. If I needed to register a service worker on example.com/product/description.html that applied to all ofexample.com, I would leave off the scope as above.
if ('serviceWorker' in navigator) {
  // Register a service worker hosted at the root of the
  // site using a more restrictive scope.
  navigator.serviceWorker.register('/sw.js', {scope: './'}).then(function(registration) {
    console.log('Service worker registration succeeded:', registration);
  }, /*catch*/ function(error) {
    console.log('Service worker registration failed:', error);
  });
} else {
  console.log('Service workers are not supported.');
}
 If your server worker is active on a client being served with the Service-Worker-Allowed header, you can specify a list of max scopes for that worker.
Note: localStorage works in a similar way to service worker cache, but it is synchronous, so not allowed in service workers.
Note: IndexedDB can be used inside a service worker for data storage if you require it.
Download, install and activate
- Download
The service worker is immediately downloaded when a user first accesses a service worker–controlled site/page.
After that, it is downloaded every 24 hours or so. It may be downloaded more frequently, but it must be downloaded every 24 hours to prevent bad scripts from being annoying for too long.
- Install
Installation is attempted when the downloaded file is found to be new — either different to an existing service worker (byte-wise compared), or the first service worker encountered for this page/site.
You can listen out for the InstallEvent; a standard action is to prepare your service worker for usage when this fires, for example by creating a cache using the built in storage API, and placing assets inside it that you'll want for running your app offline.
- Activate
If there is an existing service worker available, the new version is installed in the background, but not yet activated — at this point it is called the worker in waiting. It is only activated when there are no longer any pages loaded that are still using the old service worker. As soon as there are no more pages to be loaded, the new service worker activates (becoming the active worker). Activation can happen sooner using ServiceWorkerGlobalScope.skipWaiting() and existing pages can be claimed by the active worker using Clients.claim().
There is also an activate event. The point where this event fires is generally a good time to clean up old caches and other things associated with the previous version of your service worker.
Your service worker can respond to requests using the FetchEvent event. You can modify the response to these requests in any way you want, using the FetchEvent.respondWith method.
Because oninstall/onactivate could take a while to complete, the service worker spec provides a waitUntil method, once this is called oninstall or onactivate, it passes a promise. Functional events are not dispatched to the service worker until the promise is successfully resolved.
use case ideas
- Background data synchronization.
- Responding to resource requests from other origins.
- Receiving centralized updates to expensive-to-calculate data such as geolocation or gyroscope, so multiple pages can make use of one set of data. Client-side compiling and dependency management of CoffeeScript, less, CJS/AMD modules, etc. for development purposes. Hooks for background services.
- Custom templating based on certain URL patterns.
- Performance enhancements, for example pre-fetching resources that the user is likely to need in the near future, such as the next few pictures in a photo album.
Basic architecture
With service workers, the following steps are generally observed for basic set up:
- The service worker URL is fetched and registered via serviceWorkerContainer.register().
- If successful, the service worker is executed in a ServiceWorkerGlobalScope; this is basically a special kind of worker context, running off the main script execution thread, with no DOM access.
- The service worker is now ready to process events.
- Installation of the worker is attempted when service worker-controlled pages are accessed subsequently. An Install event is always the first one sent to a service worker (this can be used to start the process of populating an IndexedDB, and caching site assets). This is really the same kind of procedure as installing a native or Firefox OS app — making everything available for use offline.
- When the oninstall handler completes, the service worker is considered installed.
- Next is activation. When the service worker is installed, it then receives an activate event. The primary use of onactivate is for cleanup of resources used in previous versions of a Service worker script.
- The Service worker will now control pages, but only those opened after the register() is successful. i.e. a document starts life with or without a Service worker and maintains that for its lifetime. So documents will have to be reloaded to actually be controlled.


live demo
self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      return cache.addAll([
        '/sw-test/',
        '/sw-test/index.html',
        '/sw-test/style.css',
        '/sw-test/app.js',
        '/sw-test/image-list.js',
        '/sw-test/star-wars-logo.jpg',
        '/sw-test/gallery/bountyHunters.jpg',
        '/sw-test/gallery/myLittleVader.jpg',
        '/sw-test/gallery/snowTroopers.jpg'
      ]);
    })
  );
});
self.addEventListener('fetch', function(event) {
  event.respondWith(caches.match(event.request).then(function(response) {
    // caches.match() always resolves
    // but in case of success response will have value
    if (response !== undefined) {
      return response;
    } else {
      return fetch(event.request).then(function (response) {
        // response may be used only once
        // we need to save clone to put one copy in cache
        // and serve second one
        let responseClone = response.clone();
        caches.open('v1').then(function (cache) {
          cache.put(event.request, responseClone);
        });
        return response;
      }).catch(function () {
        return caches.match('/sw-test/gallery/myLittleVader.jpg');
      });
    }
  }));
});
 event

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function(resp) {
      return resp || fetch(event.request).then(function(response) {
        let responseClone = response.clone();
        caches.open('v1').then(function(cache) {
          cache.put(event.request, responseClone);
        });
        return response;
      });
    }).catch(function() {
      return caches.match('/sw-test/gallery/myLittleVader.jpg');
    })
  );
});
 Cloning the response is necessary because request and response streams can only be read once. In order to return the response to the browser and put it in the cache we have to clone it. So the original gets returned to the browser and the clone gets sent to the cache. They are each read once.
- activate
self.addEventListener('activate', function(event) {
  var cacheKeeplist = ['v2'];
  event.waitUntil(
    caches.keys().then(function(keyList) {
      return Promise.all(keyList.map(function(key) {
        if (cacheKeeplist.indexOf(key) === -1) {
          return caches.delete(key);
        }
      }));
    })
  );
});
 Developer toolsSection
Chrome has chrome://inspect/#service-workers, which shows current service worker activity and storage on a device, and chrome://serviceworker-internals, which shows more detail and allows you to start/stop/debug the worker process. In the future they will have throttling/offline modes to simulate bad or non-existent connections, which will be a really good thing.
articles
https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register
https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
Service Worker MDN英文笔记的更多相关文章
- JavaScript是如何工作的:Service Worker的生命周期及使用场景
		摘要: 理解Service Worker. 原文:JavaScript 是如何工作的:Service Worker 的生命周期及使用场景 作者:前端小智 Fundebug经授权转载,版权归原作者所有. ... 
- 前端存储 (5) - service worker 离线存储
		service worker 离线存储 简介: 一般的网站 在我们无法访问的 时候 一般 回出现 如下 该网页无法访问 service worker 构建的网站不会出现这个错误,因为所有的 请求都是先 ... 
- Service Worker的应用
		Service Worker的应用 Service worker本质上充当Web应用程序.浏览器与网络(可用时)之间的代理服务器,这个API旨在创建有效的离线体验,它会拦截网络请求并根据网络是否可用来 ... 
- Service worker (@nuxtjs/workbox) 采坑记
		PWA(Progressive Web App)是前端的大趋势,它能极大的加快前端页面的加载速度,得到近乎原生 app 的展示效果(其实难说).PWA 其实是多种前端技术的组合,其中最重要的一个技术就 ... 
- [PWA] 9. Service worker registerion && service work's props, methods and listeners
		In some rare cases, you need to ask user to refresh the browsser to update the version. Maybe becaus ... 
- [PWA] 2. Service worker life cycle
		Once serive worker is registered, the first time we go to the app, we cannot see the logs from servc ... 
- [PWA] 1. Intro to Service worker
		Service worker stays between our browser and noetwork requests. It can help to fetch data from cache ... 
- Service Worker和HTTP缓存
		很多人,包括我自己,初看Service Worker多一个Cache Storage的时候,就感觉跟HTTP长缓存没什么区别. 例如大家讲的最多的Service Worker能让网页离线使用,但熟悉H ... 
- Service Worker
		Service Worker 随着前端快速发展,应用的性能已经变得至关重要,关于这一点大佬做了很多统计.你可以去看看. 如何降低一个页面的网络请求成本从而缩短页面加载资源的时间并降低用户可感知的延时是 ... 
随机推荐
- 网站 Cookie only 唯一 防止被截获
			void Page_Load(object sender, EventArgs e) { // Create a new HttpCookie. HttpCookie myHttpCookie = n ... 
- 201771010126  王燕《面向对象设计 java》第十五周实验总结
			第一部分 理论部分 ◼ JAR文件◼ 应用程序首选项存储◼ Java Web Start JAR文件: 1.Java程序的打包:程序编译完成后,程序员将.class文件压缩打包为.jar文件后,GU ... 
- HTML入门13
			构建表格 使用colspan和rowspan添加无单位的数字值作为属性来实现行合并和列合并: <col>来定义列的样式,每一个<col>都会制定每列的样式,对于不需要指定列的样 ... 
- ionic4 开发企业微信应用0
			作为一个后台开发人员,几年前参与过Ionic1开发过一微信公众号的经历,所以这次开发企业微信应用,就使用了ionic,正好ionic4 rc版本发布,虽然不是正式版,作为本项目的项目经理,还是决定使用 ... 
- 201771010118 马昕璐 《面向对象设计 java》第十七周实验总结
			1.实验目的与要求 (1) 掌握线程同步的概念及实现技术: (2) 线程综合编程练习 2.实验内容和步骤 实验1:测试程序并进行代码注释. 测试程序1: l 在Elipse环境下调试教材651页程序1 ... 
- HBuilder git使用-建立仓库,邀请用户
			1.git环境配置好后,在Github上注册好帐号 2. 创建一个Respository(代码仓库) 3.邀请其他小组用户(必须的,要不别人提交不了修改) 4.把邀请链接要COPY给其他用户 5. 其 ... 
- go 使用 c接口
			在使用go语言时, 有时为了方便可以直接调用c语言的接口与库, 不需要重复编写. 那就来说说在go语言里面如何调用c的接口 首先编写好c语言的源文件与头文件,这里举一个简单的例子,实现一个字符串大小写 ... 
- Gem::LoadError: Specified 'sqlite3' for database adapter, but the gem is not loaded
			解决办法: 指定sqlite3的版本为1.3.13: gem 'sqlite3', '~> 1.3.13' 然后运行bundle update 
- emWin智能家居主界面设计,含uCOS-III和FreeRTOS两个版本
			第6期:智能家居主界面设计配套例子:V6-910_STemWin提高篇实验_智能家居主界面设计(uCOS-III)V6-911_STemWin提高篇实验_智能家居主界面设计(FreeRTOS) 例程下 ... 
- 【二代示波器教程】第14章 uCOS-III操作系统版本二代示波器实现
			第14章 uCOS-III操作系统版本二代示波器实现 本章教程为大家讲解uCOS-III操作系统版本的二代示波器实现.主要讲解RTOS设计框架,即各个任务实现的功能,任务间的通信方案选择,任 ... 
