SlideShare a Scribd company logo
Максим Сальников
@webmaxru
Сервис-воркеры:Сервис-воркеры:
используем накопленные знанияиспользуем накопленные знания
для светлого будущего PWAдля светлого будущего PWA
“ Что мы узнали за 3 года использования
PWA?
“ Что мы узнали за 3 года использования
PWA?
И как жить дальшеИ как жить дальше
Максим СальниковМаксим Сальников
@webmaxru@webmaxru
Google Dev Expert, Microsoft MVPGoogle Dev Expert, Microsoft MVP
Организатор Mobile / Web /Организатор Mobile / Web / PWA PWA
митапов в Осло и Лондонемитапов в Осло и Лондоне
Организатор конференцийОрганизатор конференций
Mobile Era и ngVikingsMobile Era и ngVikings
“ Full-stack разработчик "приложений
из будущего" в ForgeRock
#YearOfPWA#YearOfPWA
#YearOfPWA#YearOfPWA
Что новенького?Что новенького?
Еще одно определение PWAЕще одно определение PWA
Еще одно определение PWAЕще одно определение PWA
PWA используютPWA используют современные веб-APIсовременные веб-API вкупевкупе
со стратегией прогрессивного улучшениясо стратегией прогрессивного улучшения
для созданиядля создания кросс-платформенныхкросс-платформенных
приложений.приложений.
Еще одно определение PWAЕще одно определение PWA
PWA используютPWA используют современные веб-APIсовременные веб-API вкупевкупе
со стратегией прогрессивного улучшениясо стратегией прогрессивного улучшения
для созданиядля создания кросс-платформенныхкросс-платформенных
приложений.приложений.
Эти приложения запускаются везде и обладают
рядом характеристик, обеспечивающих
пользователей преимуществами, аналогичными
тем, что доступны в нативных решениях.
Кросс-платформенные?Кросс-платформенные?
Кросс-платформенные?Кросс-платформенные?
БраузерыБраузеры
Кросс-платформенные?Кросс-платформенные?
БраузерыБраузеры
МобильныеМобильные
Кросс-платформенные?Кросс-платформенные?
БраузерыБраузеры
НастольныеНастольные
МобильныеМобильные
Кросс-платформенные?Кросс-платформенные?
БраузерыБраузеры
НастольныеНастольные
МобильныеМобильные
Кросс-платформенные?Кросс-платформенные?
БраузерыБраузеры
НастольныеНастольные
МобильныеМобильные
Кросс-платформенные?Кросс-платформенные?
БраузерыБраузеры
НастольныеНастольные
МобильныеМобильные
Для разработчиков
Кросс-платформенные?Кросс-платформенные?
БраузерыБраузеры
НастольныеНастольные
МобильныеМобильные
Магазины?Магазины?
Для разработчиков
Новые преимущества?Новые преимущества?
Онлайн больше не обязателенОнлайн больше не обязателен
Новые преимущества?Новые преимущества?
Онлайн больше не обязателенОнлайн больше не обязателен
Получение уведомленийПолучение уведомлений
Новые преимущества?Новые преимущества?
Онлайн больше не обязателенОнлайн больше не обязателен
Масса других возможностейМасса других возможностей
Получение уведомленийПолучение уведомлений
Новые преимущества?Новые преимущества?
Онлайн больше не обязателенОнлайн больше не обязателен
Масса других возможностейМасса других возможностей
Получение уведомленийПолучение уведомлений Service Worker API
Новые преимущества?Новые преимущества?
}}
Онлайн больше не обязателенОнлайн больше не обязателен
Масса других возможностейМасса других возможностей
Получение уведомленийПолучение уведомлений Service Worker API
Web App Manifest
Новые преимущества?Новые преимущества?
Полноценное приложениеПолноценное приложение
}}
Сервис-воркерСервис-воркер
Сервис-воркерСервис-воркер
ДвигательДвигатель PWAPWA
ЛогическиЛогически ФизическиФизически
ЛогическиЛогически ФизическиФизически
Приложение
ЛогическиЛогически ФизическиФизически
Приложение
ЛогическиЛогически ФизическиФизически
Приложение
Сервис-воркер
ЛогическиЛогически ФизическиФизически
Приложение
Сервис-воркер
ЛогическиЛогически ФизическиФизически
JSJS -файл-файл
Приложение
Сервис-воркер
ИнструментарийИнструментарий
Service Worker APIService Worker API
Cache APICache API
IndexedDBIndexedDB
FetchFetch
Clients APIClients API
Broadcast Channel APIBroadcast Channel API
Push APIPush API
Notifications APINotifications API
ИнструментарийИнструментарий
Service Worker APIService Worker API
Cache APICache API
IndexedDBIndexedDB
FetchFetch
Clients APIClients API
Broadcast Channel APIBroadcast Channel API
Push APIPush API
Notifications APINotifications API
Local StorageLocal Storage
Session StorageSession Storage
XMLHttpRequestXMLHttpRequest
DOMDOM
ИнструментарийИнструментарий
Service Worker APIService Worker API
Cache APICache API
IndexedDBIndexedDB
FetchFetch
Clients APIClients API
Broadcast Channel APIBroadcast Channel API
Push APIPush API
Notifications APINotifications API
Local StorageLocal Storage
Session StorageSession Storage
XMLHttpRequestXMLHttpRequest
DOMDOM
Непростой жизненный циклНепростой жизненный цикл
https://bitsofco.de/the-service-worker-lifecycle/
Непростой жизненный циклНепростой жизненный цикл
Загрузка
https://bitsofco.de/the-service-worker-lifecycle/
Непростой жизненный циклНепростой жизненный цикл
'install'
Загрузка Установка
https://bitsofco.de/the-service-worker-lifecycle/
Непростой жизненный циклНепростой жизненный цикл
'install'
Загрузка Установка
https://bitsofco.de/the-service-worker-lifecycle/
Ожидание
Непростой жизненный циклНепростой жизненный цикл
'install'
Загрузка Установка Активация
'activate'
https://bitsofco.de/the-service-worker-lifecycle/
Ожидание
Непростой жизненный циклНепростой жизненный цикл
'install'
Загрузка Установка Активация
'activate'
https://bitsofco.de/the-service-worker-lifecycle/
Ожидание Активен
Непростой жизненный циклНепростой жизненный цикл
'install'
Загрузка Установка Активация
Удален
'activate'
https://bitsofco.de/the-service-worker-lifecycle/
Ожидание Активен
Непростой жизненный циклНепростой жизненный цикл
'install'
Загрузка Установка Активация
Удален
'activate'
https://bitsofco.de/the-service-worker-lifecycle/
Ожидание Активен
ПрогрессивныеПрогрессивные веб-веб-
приложенияприложения
ПрогрессивныеПрогрессивные веб-веб-
приложенияприложения
“ стремящийся к прогрессу,стремящийся к прогрессу,
проникнутый передовымипроникнутый передовыми
идеямиидеями
ПрогрессивныеПрогрессивные веб-веб-
приложенияприложения
“ стремящийся к прогрессу,стремящийся к прогрессу,
проникнутый передовымипроникнутый передовыми
идеямиидеями
“ постепеннопостепенно
возрастающий,возрастающий,
увеличивающийсяувеличивающийся
ПрогрессивноеПрогрессивное улучшение улучшение
Совет #1Совет #1
ПрогрессивноеПрогрессивное улучшение улучшение
Определяйте наличиеОпределяйте наличие
функциональностифункциональности
Совет #1Совет #1
https://tomayac.github.io/pwa-feature-detector/
https://tomayac.github.io/pwa-feature-detector/
РегистрацияРегистрация
if ('serviceWorker' in navigator) {
// Регистрируем сервис-воркер
}
Фоновая синхронизацияФоновая синхронизация
if ('SyncManager' in window) {
// Реализуем функциональность для оффлайн-режима
}
Подписка на pushПодписка на push
if (!('PushManager' in window)) {
// Прячем интерфейс подписки на push-уведомления
}
Действия в уведомленияхДействия в уведомлениях
if ('actions' in Notification.prototype) {
// Можем использовать кнопки с разными действиями
}
ПравильныйПравильный момент момент
для регистрациидля регистрации
Совет #2Совет #2
ПравильныйПравильный момент момент
для регистрациидля регистрации
Чем позже, тем лучшеЧем позже, тем лучше
Совет #2Совет #2
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-workbox.js')
.then(...);
}
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-workbox.js')
.then(...);
}
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw-workbox.js')
.then(...);
)};
}
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw-workbox.js')
.then(...);
)};
}
platformBrowserDynamic()
.bootstrapModule(AppModule)
.then(() => {
// Регистрация сервис-воркера
});
main.tsmain.ts
Если что-то пошлоЕсли что-то пошло
не такне так
Совет #3Совет #3
Если что-то пошлоЕсли что-то пошло
не такне так
Нужен kill switchНужен kill switch
Совет #3Совет #3
План спасенияПлан спасения
РазрегистрироватьРазрегистрировать сервис-воркер? сервис-воркер?
План спасенияПлан спасения
РазрегистрироватьРазрегистрировать сервис-воркер? сервис-воркер?
РазместитьРазместить исправленныйисправленный сервис-воркер (или    no- сервис-воркер (или    no-
op)op)
План спасенияПлан спасения
РазрегистрироватьРазрегистрировать сервис-воркер? сервис-воркер?
РазместитьРазместить исправленныйисправленный сервис-воркер (или    no- сервис-воркер (или    no-
op)op)
Удостовериться, что сервис-воркер не берется изУдостовериться, что сервис-воркер не берется из
кеша HTTPкеша HTTP
План спасенияПлан спасения
No-opNo-op
self.addEventListener('install', () => {
self.skipWaiting();
});
https://stackoverflow.com/questions/33986976/how-can-i-remove-a-buggy-service-worker-or-implement-a-kill-switch
No-opNo-op
self.addEventListener('install', () => {
self.skipWaiting();
});
self.addEventListener('activate', () => {
self.clients.matchAll({type: 'window'}).then(tabs => {
tabs.forEach(tab => {
tab.navigate(tab.url);
});
});
});
Крайняя мера для UXКрайняя мера для UX
https://stackoverflow.com/questions/33986976/how-can-i-remove-a-buggy-service-worker-or-implement-a-kill-switch
Обновление и обход кеша HTTPОбновление и обход кеша HTTP
Cache-Control: no-cache
Сервис-воркерСервис-воркер
Побайтное сравнение, нужно использоватьПобайтное сравнение, нужно использовать
версионностьверсионность
Обновление и обход кеша HTTPОбновление и обход кеша HTTP
Cache-Control: no-cache
Ресурсы, импортированные через importScripts() Ресурсы, импортированные через importScripts() 
Сервис-воркерСервис-воркер
Побайтное сравнение, нужно использоватьПобайтное сравнение, нужно использовать
версионностьверсионность
navigator.serviceWorker.register(`/sw.js?v=${VERSION}`);
Контент не проверяется, нужно менятьКонтент не проверяется, нужно менять названиеназвание
ресурсаресурса
Обновление и обход кеша HTTPОбновление и обход кеша HTTP
Cache-Control: no-cache
Ресурсы, импортированные через importScripts() Ресурсы, импортированные через importScripts() 
Сервис-воркерСервис-воркер
https://github.com/w3c/ServiceWorker/issues/893
Побайтное сравнение, нужно использоватьПобайтное сравнение, нужно использовать
версионностьверсионность Спецификация
Спецификация
обновлена
обновлена
navigator.serviceWorker.register(`/sw.js?v=${VERSION}`);
Контент не проверяется, нужно менятьКонтент не проверяется, нужно менять названиеназвание
ресурсаресурса
updateViaCacheupdateViaCache
index.htmlindex.html
https://w3c.github.io/ServiceWorker/#dfn-update-via-cache
navigator.serviceWorker.register('/sw.js', {
updateViaCache: 'none'
})
updateViaCacheupdateViaCache
index.htmlindex.html
https://w3c.github.io/ServiceWorker/#dfn-update-via-cache
navigator.serviceWorker.register('/sw.js', {
updateViaCache: 'none'
})
Значения: "Значения: "importsimports", "all" или "none"", "all" или "none"
ПредварительноеПредварительное
кешированиекеширование
Совет #4Совет #4
ПредварительноеПредварительное
кешированиекеширование
Знайте ваши ресурсы и неЗнайте ваши ресурсы и не
оставляйте мусороставляйте мусор
Совет #4Совет #4
const appShellFilesToCache = [
...
'./non-existing.html'
]
sw-handmade.jssw-handmade.js
const appShellFilesToCache = [
...
'./non-existing.html'
]
sw-handmade.jssw-handmade.js
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(cacheName).then((cache) => {
return cache.addAll(appShellFilesToCache)
})
)
})
ОшибкиОшибки HTTPHTTP
ОшибкиОшибки HTTPHTTP
Время работыВремя работы сервис-воркера сервис-воркера
ОшибкиОшибки HTTPHTTP
Время работыВремя работы сервис-воркера сервис-воркера
ОшибкиОшибки хранилищхранилищ
https://developers.google.com/web/fundamentals/instant-and-offline/web-storage/offline-for-pwa
Объем хранилищ ограниченОбъем хранилищ ограничен
https://developers.google.com/web/fundamentals/instant-and-offline/web-storage/offline-for-pwa
Chrome <6% своб. пространства
Firefox <10% своб. пространства
Safari <50MB
IE10 <250MB
Edge Зависит от размера диска
Объем хранилищ ограниченОбъем хранилищ ограничен
https://developers.google.com/web/fundamentals/instant-and-offline/web-storage/offline-for-pwa
Chrome <6% своб. пространства
Firefox <10% своб. пространства
Safari <50MB
IE10 <250MB
Edge Зависит от размера диска
if ('storage' in navigator && 'estimate' in navigator.storage) {
navigator.storage.estimate().then(({usage, quota}) => {
console.log(`Using ${usage} out of ${quota} bytes.`);
});
}
Объем хранилищ ограниченОбъем хранилищ ограничен
Кеширование ресурсов сКеширование ресурсов с
других адресовдругих адресов
Совет #5Совет #5
Кеширование ресурсов сКеширование ресурсов с
других адресовдругих адресов
ПриготовьтесьПриготовьтесь
к непрозрачностик непрозрачности
Совет #5Совет #5
2 варианта2 варианта
2 варианта2 варианта
Добавить заголовкиДобавить заголовки CORSCORS на удаленной сторонена удаленной стороне
2 варианта2 варианта
Добавить заголовкиДобавить заголовки CORSCORS на удаленной сторонена удаленной стороне
ОбрабатыватьОбрабатывать opaque ответыopaque ответы
Ограничения opaque ответовОграничения opaque ответов
https://stackoverflow.com/questions/39109789/what-limitations-apply-to-opaque-responses/39109790#39109790
Ограничения opaque ответовОграничения opaque ответов
СвойствоСвойство status всегда равно нулюstatus всегда равно нулю и не зависит от и не зависит от
того, успешен запрос или неттого, успешен запрос или нет
https://stackoverflow.com/questions/39109789/what-limitations-apply-to-opaque-responses/39109790#39109790
Ограничения opaque ответовОграничения opaque ответов
СвойствоСвойство status всегда равно нулюstatus всегда равно нулю и не зависит от и не зависит от
того, успешен запрос или неттого, успешен запрос или нет
Методы Cache APIМетоды Cache API add()add()//addAll()addAll()  сработают аварийносработают аварийно,,
если статус хотя бы одного из ответов не находится весли статус хотя бы одного из ответов не находится в
диапазоне 2XXдиапазоне 2XX
https://stackoverflow.com/questions/39109789/what-limitations-apply-to-opaque-responses/39109790#39109790
const appShellFilesToCache = [
...
'https://workboxjs.org/offline-ga.min.svg'
]
sw-handmade.jssw-handmade.js
const appShellFilesToCache = [
...
'https://workboxjs.org/offline-ga.min.svg'
]
sw-handmade.jssw-handmade.js
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(cacheName).then((cache) => {
return cache.addAll(appShellFilesToCache)
})
)
})
Решение для no-corsРешение для no-cors
const noCorsRequest =
new Request('https://workboxjs.org/offline-ga.svg', {
mode: 'no-cors'
});
fetch(noCorsRequest)
.then(response => cache.put(noCorsRequest, response));
ПравильныеПравильные инструменты инструменты
Совет #6Совет #6
ПравильныеПравильные инструменты инструменты
Доверяй И проверяйДоверяй И проверяй
Совет #6Совет #6
Инструменты помогаютИнструменты помогают
Инструменты помогаютИнструменты помогают
РеализовыватьРеализовывать сложныесложные алгоритмыалгоритмы
Инструменты помогаютИнструменты помогают
РеализовыватьРеализовывать сложныесложные алгоритмыалгоритмы
ПерениматьПеренимать лучшие практикилучшие практики
Инструменты помогаютИнструменты помогают
РеализовыватьРеализовывать сложныесложные алгоритмыалгоритмы
ПерениматьПеренимать лучшие практикилучшие практики
Фокусироваться наФокусироваться на ВАШЕЙВАШЕЙ задаче задаче
Инструменты помогаютИнструменты помогают
РеализовыватьРеализовывать сложныесложные алгоритмыалгоритмы
ПерениматьПеренимать лучшие практикилучшие практики
Фокусироваться наФокусироваться на ВАШЕЙВАШЕЙ задаче задаче
Следить заСледить за обновлениями спецификацийобновлениями спецификаций
Инструменты помогаютИнструменты помогают
РеализовыватьРеализовывать сложныесложные алгоритмыалгоритмы
ПерениматьПеренимать лучшие практикилучшие практики
Фокусироваться наФокусироваться на ВАШЕЙВАШЕЙ задаче задаче
Следить заСледить за обновлениями спецификацийобновлениями спецификаций
ОбрабатыватьОбрабатывать пограничные случаипограничные случаи
ФреймворкиФреймворки
create-react-appcreate-react-app
preact-clipreact-cli
polymer-clipolymer-cli
vue-clivue-cli
angular-cliangular-cli
ФреймворкиФреймворки
sw-precache / sw-toolboxsw-precache / sw-toolbox
WorkboxWorkbox
offline-plugin для Webpackoffline-plugin для Webpack
PWABuilder.comPWABuilder.com
create-react-appcreate-react-app
preact-clipreact-cli
polymer-clipolymer-cli
vue-clivue-cli
angular-cliangular-cli
ГенераторыГенераторы
ФреймворкиФреймворки
sw-precache / sw-toolboxsw-precache / sw-toolbox
WorkboxWorkbox
offline-plugin для Webpackoffline-plugin для Webpack
PWABuilder.comPWABuilder.com
LighthouseLighthouse
SonarwhalSonarwhal
create-react-appcreate-react-app
preact-clipreact-cli
polymer-clipolymer-cli
vue-clivue-cli
angular-cliangular-cli
ГенераторыГенераторы
АудитАудит
https://workboxjs.org
App shellApp shell
Динамическое кешированиеДинамическое кеширование Оффлайн GAОффлайн GA
Повторение неуспешных запросовПовторение неуспешных запросов
Уведомления об обновленияхУведомления об обновлениях Build-интеграцииBuild-интеграции
https://workboxjs.org
App shellApp shell
Динамическое кешированиеДинамическое кеширование Оффлайн GAОффлайн GA
Повторение неуспешных запросовПовторение неуспешных запросов
Уведомления об обновленияхУведомления об обновлениях Build-интеграцииBuild-интеграции
Возможность расширятьВозможность расширять
функциональностьфункциональность собственногособственного
сервис-воркерасервис-воркера
https://workboxjs.org
https://www.pwabuilder.com/
Генерация и валидация Web App ManifestГенерация и валидация Web App Manifest
Генерация сервис-воркераГенерация сервис-воркера
Генерация графики (иконки)Генерация графики (иконки)
https://www.pwabuilder.com/
Генерация и валидация Web App ManifestГенерация и валидация Web App Manifest
Генерация сервис-воркераГенерация сервис-воркера
Генерация графики (иконки)Генерация графики (иконки)
Генерация нативных проектов дляГенерация нативных проектов для
размещения в магазиныразмещения в магазины
приложенийприложений
https://www.pwabuilder.com/
https://sonarwhal.com
npm install -g sonarwhal
sonarwhal --init
sonarwhal https://airhorner.com
https://sonarwhal.com
npm install -g sonarwhal
sonarwhal --init
sonarwhal https://airhorner.com
npm install -g lighthouse
lighthouse https://airhorner.com
https://github.com/GoogleChrome/lighthouse
Push-Push-уведомленияуведомления
Совет #7Совет #7
Push-Push-уведомленияуведомления
Реинкарнации "всплывающихРеинкарнации "всплывающих
окон" - НЕТ!окон" - НЕТ!
Совет #7Совет #7
ПодпискаПодписка
Только послеТолько после явногоявного запроса от пользователязапроса от пользователя
ПодпискаПодписка
Только послеТолько после явногоявного запроса от пользователязапроса от пользователя
Очевидная и простаяОчевидная и простая отпискаотписка  
ПодпискаПодписка
Только послеТолько после явногоявного запроса от пользователязапроса от пользователя
Очевидная и простаяОчевидная и простая отпискаотписка  
ПодпискаПодписка
УведомленияУведомления
УведомленияУведомления
Рассмотреть всеРассмотреть все альтернативныеальтернативные варианты. варианты.
Уведомление – крайний случай.Уведомление – крайний случай.
УведомленияУведомления
Рассмотреть всеРассмотреть все альтернативныеальтернативные варианты. варианты.
Уведомление – крайний случай.Уведомление – крайний случай.
Не для массовых, но дляНе для массовых, но для индивидуальныхиндивидуальных
сообщенийсообщений
MyAirlineMyAirline
MyAirlineMyAirline
Открыта регистрация на
ваш рейс
MyAirlineMyAirline
Открыта регистрация на
ваш рейс MyAirline
MyAirlineMyAirline
Открыта регистрация на
ваш рейс MyAirline
myairline.com
myairline.com
SVO -> KUFSVO -> KUF
myairline.com
SVO -> KUFSVO -> KUF
Нажмите здесь, чтобы
зарегистрироваться
myairline.com
Ваш рейс
MY 1228
Отправление
21.09 13:45
SVO -> KUFSVO -> KUF
Нажмите здесь, чтобы
зарегистрироваться
myairline.com
СодержимоеСодержимое
Не повторяйтесь.Не повторяйтесь. Места и так мало. Места и так мало.
ОтправляйтеОтправляйте непосредственно информацию,непосредственно информацию, а не а не
факт ее поступленияфакт ее поступления
ПродумайтеПродумайте призыв к действиюпризыв к действию
Не толькоНе только
кешированиекеширование
Совет #8Совет #8
Не толькоНе только
кешированиекеширование
Используйте весь потенциалИспользуйте весь потенциал
сервис-воркерасервис-воркера
Совет #8Совет #8
Балансировщик нагрузкиБалансировщик нагрузки
https://serviceworke.rs/load-balancer.html
Балансировщик нагрузкиБалансировщик нагрузки
Перехватываем запросы и  Перехватываем запросы и  выбираемвыбираем
определенный серверопределенный сервер
https://serviceworke.rs/load-balancer.html
Балансировщик нагрузкиБалансировщик нагрузки
Перехватываем запросы и  Перехватываем запросы и  выбираемвыбираем
определенный серверопределенный сервер
Например,Например, наименее нагруженныйнаименее нагруженный  или дляили для A/BA/B
тестированиятестирования
https://serviceworke.rs/load-balancer.html
Загрузки из браузераЗагрузки из браузера
https://serviceworke.rs/local-download_service-worker_doc.html
service-worker.jsservice-worker.js
self.addEventListener('fetch', function(event) {
if(event.request.url.indexOf("download-file") !== -1) {
event.respondWith(event.request.formData().then( formdata => {
var response = new Response(formdata.get("filebody"));
response.headers.append('Content-Disposition',
'attachment; filename="' + formdata.get("filename") + '"');
return response;
}));
}
});
Загрузки из браузераЗагрузки из браузера
https://serviceworke.rs/local-download_service-worker_doc.html
service-worker.jsservice-worker.js
self.addEventListener('fetch', function(event) {
if(event.request.url.indexOf("download-file") !== -1) {
event.respondWith(event.request.formData().then( formdata => {
var response = new Response(formdata.get("filebody"));
response.headers.append('Content-Disposition',
'attachment; filename="' + formdata.get("filename") + '"');
return response;
}));
}
});
Поддержка WebP (с WASM)Поддержка WebP (с WASM)
https://medium.com/@kennethrohde/on-the-fly-webp-decoding-using-wasm-and-a-service-worker-33e519d8c21e
service-worker.jsservice-worker.js
event.respondWith(async function() {
const response = await fetch(event.request);
const buffer = await response.arrayBuffer();
const WebPDecoder = await fetchWebPDecoder();
const decoder = new WebPDecoder(buffer);
const blob = await decoder.decodeToBMP();
return new Response(blob, { headers: { "content-type": "image/bmp",
"status": 200 } });
}());
Поддержка WebP (с WASM)Поддержка WebP (с WASM)
https://medium.com/@kennethrohde/on-the-fly-webp-decoding-using-wasm-and-a-service-worker-33e519d8c21e
service-worker.jsservice-worker.js
event.respondWith(async function() {
const response = await fetch(event.request);
const buffer = await response.arrayBuffer();
const WebPDecoder = await fetchWebPDecoder();
const decoder = new WebPDecoder(buffer);
const blob = await decoder.decodeToBMP();
return new Response(blob, { headers: { "content-type": "image/bmp",
"status": 200 } });
}());
bit.ly/bit.ly/go-pwa-slackgo-pwa-slack
1400+ разработчиков1400+ разработчиков
Представители основных браузеров,Представители основных браузеров,
библиотек, фреймворковбиблиотек, фреймворков
Совет #9Совет #9
t.me/t.me/pwa_rupwa_ru
Все о PWA на русском языкеВсе о PWA на русском языке
Спасибо!Спасибо!
@webmaxru@webmaxru
Максим СальниковМаксим Сальников
НовыеНовые функциифункции
Совет #9Совет #9
НовыеНовые функциифункции
Еще в разработкеЕще в разработке
Совет #9Совет #9
Периодическая синхронизацияПериодическая синхронизация
Периодическая синхронизацияПериодическая синхронизация
ОграничениеОграничение временным интервалом, состоянием временным интервалом, состоянием
батареи, режимом подключения к сетибатареи, режимом подключения к сети
Периодическая синхронизацияПериодическая синхронизация
ОграничениеОграничение временным интервалом, состоянием временным интервалом, состоянием
батареи, режимом подключения к сетибатареи, режимом подключения к сети
ТребуетТребует явного разрешенияявного разрешения со сторонысо стороны
пользователяпользователя
Периодическая синхронизацияПериодическая синхронизация
ОграничениеОграничение временным интервалом, состоянием временным интервалом, состоянием
батареи, режимом подключения к сетибатареи, режимом подключения к сети
ТребуетТребует явного разрешенияявного разрешения со сторонысо стороны
пользователяпользователя
Не требуется поддержкиНе требуется поддержки со стороны серверасо стороны сервера
Периодическая синхронизацияПериодическая синхронизация
ОграничениеОграничение временным интервалом, состоянием временным интервалом, состоянием
батареи, режимом подключения к сетибатареи, режимом подключения к сети
ТребуетТребует явного разрешенияявного разрешения со сторонысо стороны
пользователяпользователя
Не требуется поддержкиНе требуется поддержки со стороны серверасо стороны сервера
Финальное решение по запуску –Финальное решение по запуску – за браузеромза браузером
navigator.serviceWorker.ready.then((registration) => {
registration.periodicSync.register({
tag: 'get-latest-news', // default: ''
minPeriod: 12 * 60 * 60 * 1000, // default: 0
powerState: 'avoid-draining', // default: 'auto'
networkState: 'avoid-cellular' // default: 'online'
}).then((periodicSyncReg) => {
// Задача успешно зарегистрирована
})
});
index.htmlindex.html
self.addEventListener('periodicsync', function(event) {
if (event.registration.tag == 'get-latest-news') {
event.waitUntil(fetchAndCacheLatestNews());
}
else {
// Неизвестная задача, лучше отменить регистрацию
event.registration.unregister();
}
});
sw-handmade.jssw-handmade.js
bit.ly/bit.ly/go-pwa-slackgo-pwa-slack
1400+ разработчиков1400+ разработчиков
Представители основных браузеров,Представители основных браузеров,
библиотек, фреймворковбиблиотек, фреймворков
Совет #10Совет #10
t.me/t.me/pwa_rupwa_ru
Все о PWA на русском языкеВсе о PWA на русском языке
Спасибо!Спасибо!
@webmaxru@webmaxru
Максим СальниковМаксим Сальников
Есть вопрос?Есть вопрос?

More Related Content

Similar to [Russian] Сервис-воркеры: используем накопленные знания для светлого будущего PWA

Система мониторинга производительности своими руками (QA Fest 2016)
Система мониторинга производительности своими руками (QA Fest 2016)Система мониторинга производительности своими руками (QA Fest 2016)
Система мониторинга производительности своими руками (QA Fest 2016)
Alexander Nedeliaev
 
Vladimir Trandafilov - When you need your system of cross browser testing
Vladimir Trandafilov - When you need your system of cross browser testingVladimir Trandafilov - When you need your system of cross browser testing
Vladimir Trandafilov - When you need your system of cross browser testing
Ievgenii Katsan
 
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
Oleksii Okhrymenko
 
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)
Ontico
 
QaApi: взгляд на тестирование с другой стороны баррикад
QaApi: взгляд на тестирование с другой стороны баррикадQaApi: взгляд на тестирование с другой стороны баррикад
QaApi: взгляд на тестирование с другой стороны баррикад
Dmitry Maruschenko
 
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
AvitoTech
 
Spring in java
Spring in javaSpring in java
Spring in java
Asya Dudnik
 
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлениюCodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлениюCodeFest
 
Symfony в архитектуре Upwork Enterprise
Symfony в архитектуре Upwork EnterpriseSymfony в архитектуре Upwork Enterprise
Symfony в архитектуре Upwork Enterprise
Dmitry Semenov
 
JPoint 2017 - Where is my service, dude?
JPoint 2017 - Where is my service, dude?JPoint 2017 - Where is my service, dude?
JPoint 2017 - Where is my service, dude?
Viet Nguyen
 
Владимир Еремин. Extending Openstack. PyCon Belarus 2015
Владимир Еремин. Extending Openstack. PyCon Belarus 2015Владимир Еремин. Extending Openstack. PyCon Belarus 2015
Владимир Еремин. Extending Openstack. PyCon Belarus 2015
Alina Dolgikh
 
Аналитика мобильного проекта — проверяй и доверяй / Александр Лукин (Yandex A...
Аналитика мобильного проекта — проверяй и доверяй / Александр Лукин (Yandex A...Аналитика мобильного проекта — проверяй и доверяй / Александр Лукин (Yandex A...
Аналитика мобильного проекта — проверяй и доверяй / Александр Лукин (Yandex A...
Ontico
 
Александр Лукин
Александр ЛукинАлександр Лукин
Александр Лукин
CodeFest
 
Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими руками
Roman Dvornov
 
Middleware
MiddlewareMiddleware
Middleware
megakott
 
MBLT16: Alexander Lukin, AppMetrica
MBLT16: Alexander Lukin, AppMetricaMBLT16: Alexander Lukin, AppMetrica
MBLT16: Alexander Lukin, AppMetrica
e-Legion
 
CodeFest 2011. Высоцкий С. — Crawljax. Четвертый закон робототехники
CodeFest 2011. Высоцкий С. — Crawljax. Четвертый закон робототехникиCodeFest 2011. Высоцкий С. — Crawljax. Четвертый закон робототехники
CodeFest 2011. Высоцкий С. — Crawljax. Четвертый закон робототехникиCodeFest
 
Практические примеры использования API в инфраструктурных продуктах Cisco для...
Практические примеры использования API в инфраструктурных продуктах Cisco для...Практические примеры использования API в инфраструктурных продуктах Cisco для...
Практические примеры использования API в инфраструктурных продуктах Cisco для...
Cisco Russia
 
2014-08-02 03 Дмитрий Шматко. Первые впечатления от Node.js
2014-08-02 03 Дмитрий Шматко. Первые впечатления от Node.js2014-08-02 03 Дмитрий Шматко. Первые впечатления от Node.js
2014-08-02 03 Дмитрий Шматко. Первые впечатления от Node.js
Омские ИТ-субботники
 
Эволюция экосистем тестирования
Эволюция экосистем тестированияЭволюция экосистем тестирования
Эволюция экосистем тестированияGleb Rybalko
 

Similar to [Russian] Сервис-воркеры: используем накопленные знания для светлого будущего PWA (20)

Система мониторинга производительности своими руками (QA Fest 2016)
Система мониторинга производительности своими руками (QA Fest 2016)Система мониторинга производительности своими руками (QA Fest 2016)
Система мониторинга производительности своими руками (QA Fest 2016)
 
Vladimir Trandafilov - When you need your system of cross browser testing
Vladimir Trandafilov - When you need your system of cross browser testingVladimir Trandafilov - When you need your system of cross browser testing
Vladimir Trandafilov - When you need your system of cross browser testing
 
Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2Превышаем скоростные лимиты с Angular 2
Превышаем скоростные лимиты с Angular 2
 
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)
Превышаем скоростные лимиты с Angular 2 / Алексей Охрименко (IPONWEB)
 
QaApi: взгляд на тестирование с другой стороны баррикад
QaApi: взгляд на тестирование с другой стороны баррикадQaApi: взгляд на тестирование с другой стороны баррикад
QaApi: взгляд на тестирование с другой стороны баррикад
 
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
Rempl — крутая платформа для крутых инструментов - Роман Дворнов (Avito)
 
Spring in java
Spring in javaSpring in java
Spring in java
 
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлениюCodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
CodeFest 2013. Родионов А. — От Selenium к Watir — путь к просветлению
 
Symfony в архитектуре Upwork Enterprise
Symfony в архитектуре Upwork EnterpriseSymfony в архитектуре Upwork Enterprise
Symfony в архитектуре Upwork Enterprise
 
JPoint 2017 - Where is my service, dude?
JPoint 2017 - Where is my service, dude?JPoint 2017 - Where is my service, dude?
JPoint 2017 - Where is my service, dude?
 
Владимир Еремин. Extending Openstack. PyCon Belarus 2015
Владимир Еремин. Extending Openstack. PyCon Belarus 2015Владимир Еремин. Extending Openstack. PyCon Belarus 2015
Владимир Еремин. Extending Openstack. PyCon Belarus 2015
 
Аналитика мобильного проекта — проверяй и доверяй / Александр Лукин (Yandex A...
Аналитика мобильного проекта — проверяй и доверяй / Александр Лукин (Yandex A...Аналитика мобильного проекта — проверяй и доверяй / Александр Лукин (Yandex A...
Аналитика мобильного проекта — проверяй и доверяй / Александр Лукин (Yandex A...
 
Александр Лукин
Александр ЛукинАлександр Лукин
Александр Лукин
 
Remote (dev)tools своими руками
Remote (dev)tools своими рукамиRemote (dev)tools своими руками
Remote (dev)tools своими руками
 
Middleware
MiddlewareMiddleware
Middleware
 
MBLT16: Alexander Lukin, AppMetrica
MBLT16: Alexander Lukin, AppMetricaMBLT16: Alexander Lukin, AppMetrica
MBLT16: Alexander Lukin, AppMetrica
 
CodeFest 2011. Высоцкий С. — Crawljax. Четвертый закон робототехники
CodeFest 2011. Высоцкий С. — Crawljax. Четвертый закон робототехникиCodeFest 2011. Высоцкий С. — Crawljax. Четвертый закон робототехники
CodeFest 2011. Высоцкий С. — Crawljax. Четвертый закон робототехники
 
Практические примеры использования API в инфраструктурных продуктах Cisco для...
Практические примеры использования API в инфраструктурных продуктах Cisco для...Практические примеры использования API в инфраструктурных продуктах Cisco для...
Практические примеры использования API в инфраструктурных продуктах Cisco для...
 
2014-08-02 03 Дмитрий Шматко. Первые впечатления от Node.js
2014-08-02 03 Дмитрий Шматко. Первые впечатления от Node.js2014-08-02 03 Дмитрий Шматко. Первые впечатления от Node.js
2014-08-02 03 Дмитрий Шматко. Первые впечатления от Node.js
 
Эволюция экосистем тестирования
Эволюция экосистем тестированияЭволюция экосистем тестирования
Эволюция экосистем тестирования
 

More from Maxim Salnikov

Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?
Maxim Salnikov
 
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
Maxim Salnikov
 
Building Generative AI-infused apps: what's possible and how to start
Building Generative AI-infused apps: what's possible and how to startBuilding Generative AI-infused apps: what's possible and how to start
Building Generative AI-infused apps: what's possible and how to start
Maxim Salnikov
 
Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?
Maxim Salnikov
 
ChatGPT and not only: how can you use the power of Generative AI at scale
ChatGPT and not only: how can you use the power of Generative AI at scaleChatGPT and not only: how can you use the power of Generative AI at scale
ChatGPT and not only: how can you use the power of Generative AI at scale
Maxim Salnikov
 
Using the power of OpenAI with your own data: what's possible and how to start?
Using the power of OpenAI with your own data: what's possible and how to start?Using the power of OpenAI with your own data: what's possible and how to start?
Using the power of OpenAI with your own data: what's possible and how to start?
Maxim Salnikov
 
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
Maxim Salnikov
 
Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?
Maxim Salnikov
 
ChatGPT and not only: How to use the power of GPT-X models at scale
ChatGPT and not only: How to use the power of GPT-X models at scaleChatGPT and not only: How to use the power of GPT-X models at scale
ChatGPT and not only: How to use the power of GPT-X models at scale
Maxim Salnikov
 
How Azure helps to build better business processes and customer experiences w...
How Azure helps to build better business processes and customer experiences w...How Azure helps to build better business processes and customer experiences w...
How Azure helps to build better business processes and customer experiences w...
Maxim Salnikov
 
Using the power of Generative AI at scale
Using the power of Generative AI at scaleUsing the power of Generative AI at scale
Using the power of Generative AI at scale
Maxim Salnikov
 
Web Push Notifications done right
Web Push Notifications done rightWeb Push Notifications done right
Web Push Notifications done right
Maxim Salnikov
 
The Status of Angular v13
The Status of Angular v13The Status of Angular v13
The Status of Angular v13
Maxim Salnikov
 
Azure cloud for the web frontend developers
Azure cloud for the web frontend developersAzure cloud for the web frontend developers
Azure cloud for the web frontend developers
Maxim Salnikov
 
[Russian] Прогрессивные веб-приложения: по-настоящему кросс-платформенный опыт
[Russian] Прогрессивные веб-приложения: по-настоящему кросс-платформенный опыт[Russian] Прогрессивные веб-приложения: по-настоящему кросс-платформенный опыт
[Russian] Прогрессивные веб-приложения: по-настоящему кросс-платформенный опыт
Maxim Salnikov
 
Securing Connected Cars Requires Digital Identity
Securing Connected Cars Requires Digital IdentitySecuring Connected Cars Requires Digital Identity
Securing Connected Cars Requires Digital Identity
Maxim Salnikov
 
How to Make Your IoT Devices Secure, Act Autonomously & Trusted Subjects
How to Make Your IoT Devices Secure, Act Autonomously & Trusted SubjectsHow to Make Your IoT Devices Secure, Act Autonomously & Trusted Subjects
How to Make Your IoT Devices Secure, Act Autonomously & Trusted Subjects
Maxim Salnikov
 

More from Maxim Salnikov (17)

Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?
 
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
 
Building Generative AI-infused apps: what's possible and how to start
Building Generative AI-infused apps: what's possible and how to startBuilding Generative AI-infused apps: what's possible and how to start
Building Generative AI-infused apps: what's possible and how to start
 
Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?
 
ChatGPT and not only: how can you use the power of Generative AI at scale
ChatGPT and not only: how can you use the power of Generative AI at scaleChatGPT and not only: how can you use the power of Generative AI at scale
ChatGPT and not only: how can you use the power of Generative AI at scale
 
Using the power of OpenAI with your own data: what's possible and how to start?
Using the power of OpenAI with your own data: what's possible and how to start?Using the power of OpenAI with your own data: what's possible and how to start?
Using the power of OpenAI with your own data: what's possible and how to start?
 
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
If your code could speak, what would it tell you? Let GitHub Copilot Chat hel...
 
Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?Prompt Engineering - an Art, a Science, or your next Job Title?
Prompt Engineering - an Art, a Science, or your next Job Title?
 
ChatGPT and not only: How to use the power of GPT-X models at scale
ChatGPT and not only: How to use the power of GPT-X models at scaleChatGPT and not only: How to use the power of GPT-X models at scale
ChatGPT and not only: How to use the power of GPT-X models at scale
 
How Azure helps to build better business processes and customer experiences w...
How Azure helps to build better business processes and customer experiences w...How Azure helps to build better business processes and customer experiences w...
How Azure helps to build better business processes and customer experiences w...
 
Using the power of Generative AI at scale
Using the power of Generative AI at scaleUsing the power of Generative AI at scale
Using the power of Generative AI at scale
 
Web Push Notifications done right
Web Push Notifications done rightWeb Push Notifications done right
Web Push Notifications done right
 
The Status of Angular v13
The Status of Angular v13The Status of Angular v13
The Status of Angular v13
 
Azure cloud for the web frontend developers
Azure cloud for the web frontend developersAzure cloud for the web frontend developers
Azure cloud for the web frontend developers
 
[Russian] Прогрессивные веб-приложения: по-настоящему кросс-платформенный опыт
[Russian] Прогрессивные веб-приложения: по-настоящему кросс-платформенный опыт[Russian] Прогрессивные веб-приложения: по-настоящему кросс-платформенный опыт
[Russian] Прогрессивные веб-приложения: по-настоящему кросс-платформенный опыт
 
Securing Connected Cars Requires Digital Identity
Securing Connected Cars Requires Digital IdentitySecuring Connected Cars Requires Digital Identity
Securing Connected Cars Requires Digital Identity
 
How to Make Your IoT Devices Secure, Act Autonomously & Trusted Subjects
How to Make Your IoT Devices Secure, Act Autonomously & Trusted SubjectsHow to Make Your IoT Devices Secure, Act Autonomously & Trusted Subjects
How to Make Your IoT Devices Secure, Act Autonomously & Trusted Subjects
 

[Russian] Сервис-воркеры: используем накопленные знания для светлого будущего PWA