Комментарии 40
Остальные на первый взгляд сладкие варианты кэширования как то .cacheFirst чреваты и требуют многодневного тестирования, и что важно, сложного обслуживания/поддержки.
- При использовании SW как прокси мы получаем довольно не плохую задержку в загрузке (-5% -5% +25%)
- Пуши — почему то многие о них умалчивают когда говорят о SW а тем не менее это довольно крутая штука.
Как по мне, так использовать SW нужно очень обдуманно. Потому что базовые операции по кешированию отлично могут выполнить заголовки файлов. Отдал заголовок с кешем на месяц, и файл будет браться из кеша браузера. Выкатил новую версию файла, дописал v=number в url. Где здесь SW?
С оффлайном да, хорошая идея, но опять же много чего в оффлайн не засунешь.
Как я знаю поддержка в таких браузерах как Safari или Edge находится в разработке.
Поэтому данная технология довольно-таки перспективна на мой взгляд.
Ровно как и часть крупных приложений уже начинают использовать их на проде (twitter, tinder, pinterest, smashingmagazine).
2 и 3
-5% -5% +25% — как сказал Артём Белов: “… сначала забирает, а потом добавляет с лихвой...”
По поводу прокси, пушей и как настроить общение между воркером и веб-страницей ещё будет статья. Тут идея была расписать базовые стратегии для кэширования и как их использовать, по сути “на пальцах“.
Касательно, выставить заголовки и т.п.
Базовые средства оптимизации никто не отменяет)
Кешировать надо все, что только возможно (с умом естественно), просто SW может помочь сделать приложение более отзывчивым и ускорить его отображение пользователю.
По поводу оффлайна:
А всё ли надо засовывать в оффлайн? На мой взгляд нужно лишь класть критичные файлы (css, js, html) и правильно обрабатывать ситуацию, когда нет доступа к сети, оставляя пользователя в приложении, а не заставляя его ждать минуту и в итоге показать Динозаврика.
Статья задумывалась начальной в серии статей о SW API. Хочется понять, насколько тема интересна и полезна. Жду ваших комментариев и пожеланий.
В общем, продолжайте!
Все еще непонятно, чем кэширование js/css с помощью SW лучше обычного кэширования на основе заголовков. Можете привести конкретный пример, где решение с SW подходит лучше?
Отдать закешированный ответ, а в фоне скачать новый для следующего запроса.
Непонятно. Если уже есть закэшированный — зачем качать еще раз?
Если новая версия отличается от закэшированной — зачем отдавать юзеру старую версию? Без хот релоада юзер так и не увидит изменений — нужно будет обновить страницу.
Есть конкретный пример, где это имеет смысл?
Есть конкретный пример, где это имеет смысл?Я чуть-чуть подправил код и для меня в принципе не страшно, если юзер еще один заход будет пользоваться старой версией приложения вместо того, чтобы получить задержку на скачивание нового бандла. В конце концов, я могу показать кнопку «доступна новая версия, обновить страницу».
в принципе не страшно, если юзер еще один заход будет пользоваться старой версией
Но бывают же и изменения, которые надо юзеру сразу доставить (например, старая версия кода несовместима с новой разметкой, которую генерит CMS, или с новым API).
Как отличать эти "важные" изменения от "неважных", чтобы SW отдавал закэшированную версию в одном случае, но не в другом?
И еще такой момент. В реальном приложении нельзя полагаться исключительно на SW — так как есть неподдерживающие его браузеры. Значит, у вас уже предусмотрена система кэширования с возможностью инвалидации кэша при новых релизах. Например, добавляем параметр ?v=< version> к url ресурсов. Или, согласно рекомендации от webpack, дописываем хэш файла, посчитанный при сборке.
В результате при изменении кода URL меняется — и SW не найдет измененный файл в своем кэше.
Я вот все пытаюсь найти реальный случай, где кэширование с SW имеет смысл и работает. Что за сайт/приложение, какая там стратегия кэширования, что именно кэшируется и как инвалидируется, и какой именно сценарий использования мы пытаемся улучшить с помощью SW.
В результате при изменении кода URL меняется — и SW не найдет измененный файл в своем кэше.только если вы так запрограммируете. Срезайте ?v=3 в обработчике запроса в коде SW, например.
Как отличать эти «важные» изменения от «неважныхТут аналогичный ответ — вы пишете код, так что как хотите. Добавьте параметр &major-version=3 например.
В теории звучит ясно, но дьявол, как всегда, в деталях. Здорово было бы увидеть реальный пример реализации. Ни одной статьи с описанием такого подхода мне не попадалось.
Наиболее осмысленное применение кэша в SW из примеров, которые я видел в интернете: пре-кэшинг файлов в связке с HTTP/2 Server Push — для решения проблемы с кэшем, присущей Server Push (например, тут).
А чтобы получить заголовок кэширования обычными методами серва, нужна сеть.
Неправда. Если файл уже закэширован браузером после первого запроса, то последующие запросы к нему выполняются без сети. Я имею в виду безусловное кэширование типа Cache-Control:max-age=<много-много секунд>
(в отличие от условного кэширования с ETag/If-Modified-Since).
Для самого первого запроса сеть, конечно, нужна. Ну так и с SW первый запрос требует сети, когда кэш еще не заполнен.
Неправда. Если файл уже закэширован браузером после первого запроса, то последующие запросы к нему выполняются без сети.
Ключевое здесь файл. Статика. В случае кэширования в cacheStorage можно положить text/html response. При чем положить заранее, при первом обращении к серверу. При чем respone на любой request.url. То есть фактически при первом обращении задать список доступных оффлайн страниц.
В случае кэширования в cacheStorage можно положить text/html response
Да, про такой сценарий я не подумал. Обычно саму страницу никто "жестко" (с Cache-Control: max-age) кэшировать не станет. В этом случае SW позволит сделать фоллбэк на оффлайн-режим при отсутствии сети.
Хотя лично мне кажется, что оффлайн режим имеет очень ограниченную область применения. Имхо, не так много реальных приложений, в которых можно сделать что-то осмысленное без сети (типа написания черновика письма в gmail).
То есть фактически при первом обращении задать список доступных оффлайн страниц.
Ясно, pre-caching. Причем, "доступных оффлайн" — здесь даже необязательная часть. Сама страница может требовать сети для работы, но мы все еще можем заранее для нее что-то подгрузить.
Обычно саму страницу никто «жестко» (с Cache-Control: max-age) кэшировать не станетЗависит от сценария, который реализуется. Как правило при первом обращении кэшируется вся статика необходимая для работы сайта/приложения и какой-то список страниц: rg.ru последние N новостей и показывает плашку «Ой! У вас нет интернета.», видел магазин который клал в кэш сразу все инфо страницы, сайт рекламного агентства — страницы оферов и их описаний.
Использую для выполнения фоновых операций, +push уведомления юзерам о статусе этих операций и возможном прекращении их выполнения(если видно что закрыты все вкладки).
Как результат например общая для всех вкладок область видимости/«глобальная асинхронность», то есть если юзер открыл сервис в нескольких вкладках он не может запустить занового идентичный процесс, т.к. этот процесс идет в едином сервис-воркере.
habrahabr.ru/company/2gis/blog/345552/#comment_10586162
О каких именно проблемах вы говорите? Поддержки сейчас нет в Safari — это правда, но как минимум SW в разработке для Safari и Edge.
Если мы говорим о SPA, то подобную задачу можно решить через тот же redux и управлением данными через store, то есть вы сами контролируете, какой листинг вы открыли и если есть данные в store, то запрос можно не делать, а брать данные прямиком из хранилища.
Да, я понимаю, что сайт сломается, если отключить JavaScript, плюс могут быть микро-задержки на клиентский рендеринг — но проблему с кэшированием это ведь решит?
Клиент будет делать запрос на сервер и ждать, когда загрузиться html и всё остальное.
В SW иначе, первым делом достаются данные из кеша SW, а потом остальное Тем самым время Time to Interactive сводится к минимуму, т.к. не зависит от сети.
Как итог показываем, что приложение работает, но проблема ответа в скорости сети (так себя ведут мобильные приложения)
Во время сёрфинга по сайту в contentCache пишется text/html и соответственно при cacheFirst отдается из кэша. Так вот именно его нужно обновлять при определенных действиях: добавили в корзину, удалил, добавил в избранное, к сравнению, лайк\дизлайк, оставил комментарий. Потому что он хранит контент до этих действий. Надеюсь так понятнее :)
И вот такой костыль решает задачу, но чувствую что есть нативное решение.
function updateCacheByName (cacheName,updateRequestsArray) {
caches.delete(cacheName)
.then(function(){
console.log('удалили кэш '+cacheName+' чтобы обновить');
caches.open(cacheName).then(cache => {
return cache.addAll(updateRequestsArray).then(function(){
console.log('история обновлена в кэше '+cacheName);
}).catch( err => {console.log(err);});
});
}).catch( err => {console.log(err);});
}
Мне нравятся статьи, в которых последовательно наращивается уровень материала.
Про технологию узнал впервые, полез смотреть поддержку браузеров, выше была ссылка.
В общем, я за продолжение.
Поэтому:
Существует проблема, когда браузер по умолчанию выдаёт вам сообщение о том, что вы офлайн
как по мне, так это не проблема, а вполне понятное, чёткое и однозначное информирование о том что интернета пока нет, займись чем-то другим!
Моё мнение, что для сервисов, где есть плотное взаимодействие с пользователем, или контентных сервисов — подход «offline first» неудачный. Он годится лишь для чисто клиентских самодостаточных приложений (типа как тот гудящий горн на google developers, который приводят везде в пример)
p.s. хотя подозреваю, я тут напутал и намешал с pwa..))
Да, PWA это про SW, но SW — это не про PWA.
> как по мне, так это не проблема, а вполне понятное, чёткое и однозначное информирование о том что интернета пока нет, займись чем-то другим!
Как я вижу в плане дизайна приложения был допущена ошибка, что пользователь явно не показал, что вы в Offline. По мне это решается довольно просто:
window.addEventListener('offline', () => showOfflineBar());
Это уже проблема приложения, а не SW. Как я выше писал в своей статье, наша задача не просто не показывать «динозаврика», а показать своего «динозаврика» в стиле нашего приложения и была «наша» кнопка «обновить».
Одним словом, вы не спутали здесь синхронное исполнение кода и вызов, блокирующий процесс?
Я ничего против воркеров и сервис-воркеров не имею, просто почему синхронность стала проблемой?
if (!('serviceWorker' in navigator)){ return; }
Через прошедшие годы смотрим на эту задумку и видим, что как всегда интересную технологию стали абьюзить все кому не лень. Прикручивать в нее не только уведомления, кеши, но и распределенные вычисления на клиентах у пользователей без их ведома. Тысячи воркеров на клиентах грузят проц как не в себя и пользователи негодуют. А все почему? Потому, что гугл не озаботился дать механизмы управления этой штукой в руки самого пользователя, а оставил все на откуп эффективным совам из компаний, которые эти сервисы с воркерами и пилят. В итоге количество статей "как навсегда заблокировать регистрацию service workers в chrome" растет как на дрожжах. Ну и правильно, туда ей и дорога.
Подскажите мне гулпцу, пожалуйста. В сервис ворках реализуется такой же механизм как у функций обратного вызова (callback)? Или это совершенно разные вещи, которые нельзя сопоставлять?
Service Workers. Инструкция по применению