Как обеспечить отображение картинки при отсутствии интернета
Что проверяют
Знаете ли вы, какие механизмы кэширования есть у браузера и чем они отличаются по надёжности. Ответ «повесим onerror» показывает, что вы думаете о симптоме, а не о том, где картинка будет лежать без сети. Следом обычно спрашивают про обновление закэшированных картинок и лимиты хранилища.
Как отвечать
Разложите по уровням, от простого к надёжному:
- HTTP-кэш: картинки с хэшем в имени отдаются с
Cache-Control: max-age=31536000, immutable, и свежую копию браузер покажет без сети. Гарантии нет: браузер вытесняет кэш когда угодно; - Service Worker и Cache API: при
installв кэш заранее кладутся критичные картинки и заглушка, вfetchдля запросов сrequest.destination === 'image'работает стратегия cache first. На практике это пишут через Workbox:CacheFirstсExpirationPlugin, который ограничивает число записей и их возраст; - заглушка при промахе: если картинки нет ни в кэше, ни в сети, воркер ловит ошибку
fetchи отдаёт закэшированный плейсхолдер вместо иконки битого изображения; - встраивание: логотип и иконки интерфейса можно отдать инлайн-SVG или маленьким data URI, тогда сеть им не нужна вовсе;
- пользовательские файлы: фото, которые человек загрузил или открыл, сохраняют в IndexedDB как
Blobи показывают черезURL.createObjectURL.
Назовите ограничения. Service Worker работает только по HTTPS или на localhost. Хранилище ограничено квотой: её проверяют через navigator.storage.estimate() и просят сделать постоянной через navigator.storage.persist(). Safari стирает записанные скриптами данные сайта, с которым пользователь неделю не взаимодействовал.
Где спотыкаются
Опираются на navigator.onLine. Он сообщает только о подключении к какой-то сети, а не о доступности сервера, и в кафе с порталом авторизации вернёт true.
Кэшируют картинки с чужого домена без CORS. Ответ получается непрозрачным, статус не виден, в кэш легко попадает ошибка вместо картинки, а Chrome засчитывает такие ответы в квоту с большим запасом.
Кладут в кэш всё подряд без лимита и версии. Через месяц кэш занимает сотни мегабайт, а обновлённая картинка не доезжает, потому что cache first отдаёт старую.