SW

Andrey Makarov aka r3nya

SW

by Andrey Makarov

Offline first

Ok! Let's go … 🤔

  1. AppCache (guide, spec)
  2. Service Workers …

sitename.appcache

			CACHE MANIFEST
			# v1 2017-30-01
			CACHE:
			index.html
			css/style.css
			js/app.js
			FALLBACK:
			/ /offline.html
		

AppCache

Can I Use offline-apps? Data on support for the offline-apps feature across the major browsers from caniuse.com.

:(

Jake Archibald – Application Cache is a Douchebag

Service Worker? WTF?

Service Workers

Can I Use serviceworkers? Data on support for the serviceworkers feature across the major browsers from caniuse.com.

			if ('serviceWorker' in navigator) {
			  window.addEventListener('load', () => {
			    navigator.serviceWorker.register('/sw.js')
			      .then((registration) => {
			      // Регистрация успешна
			      console.log('Tada! 🎉', registration.scope);
			    }).catch((err) => console.log('Fail: ', err));
			  });
			}
		

Установка Service Worker’а

			self.addEventListener('install', (event) => {
			  // установка
			  // …
			});
		
			const CACHE_NAME = 'my-site-cache-v1';
			const urlsToCache = [
			  '/', '/script/main.js', '/styles/main.css',
			];
			 
			self.addEventListener('install', (event) => {
			  event.waitUntil(
			    caches.open(CACHE_NAME).then((cache) => {
			      return cache.addAll(urlsToCache);
			    })
			  });
			});
		

Кеш и обработка запросов

			self.addEventListener('fetch', (event) => {
			  console.log(event.request);
			});
		
			self.addEventListener('fetch', (event) => {
			  console.log(event.request);
			  console.log(event.request.url);
			  console.log(event.request.method);
			  console.log(event.request.headers);
			});
		
			self.addEventListener('fetch', (event) => {
			  event.respondWith(
			    caches.match(event.request)
			      .then((response) => {
			        // ресурс есть в кеше
			        if (response) return response;
			  
			        return fetch(event.request);
			     })
			  );
			});
		
			const fetchRequest = event.request.clone();
			return fetch(fetchRequest).then((response) => {
			  if (!response || response.status !== 200 || response.type !== 'basic') {
			    return response;
			  }
			 
			  const responseToCache = response.clone();
			  caches.open(CACHE_NAME).then((cache) => {
			    cache.put(event.request, responseToCache);
			  });
			 
			  return response;
			});
		

Обновление Service Worker’а

  1. Юзер заходит на сайт → браузер скачивает файл Service Worker’а (SW).
  2. Если SW новый, срабатывает событие install.
  3. На этом этапе старый SW по прежнему контролирует страницу, тогда как новый переходит в состояние waiting.
  4. Юзер закрывает текущие открытые страницы → старый SW будет убит, а новый получит контроль.
  5. Когда новый SW получит контроль над страницей, сработает событие activate.
			self.addEventListener('activate', (event) => {
			  const cacheWhitelist = ['pages-cache-v1', 'blog-posts-cache-v1'];
			 
			  event.waitUntil(
			    return Promise.all(
			      caches.keys().then((cacheNames) => {
			        cacheNames.map((cacheName) => {
			          if (!cacheWhitelist.includes(cacheName)) {
			            return caches.delete(cacheName);
			          }
			        })
			      );
			  })
			);
		

Service Worker Precache

Service Worker Toolbox (sw-toolbox)

			toolbox.router.get('/api', toolbox.networkFirst);
			toolbox.router.get('/avatars', toolbox.cacheFirst);
			toolbox.router.get('/posts', toolbox.fasters);
		

🚀

Docs / Examples

???

WAT?!1

@r3nya

qrcode