Практическая работа №10: Progressive Web App — Список покупок
Цель работы: Научиться создавать PWA-приложение, которое можно установить на устройство, запускать как отдельное окно, использовать без интернета, хранить и редактировать данные локально в браузере. По итогам работы студент должен получить многофункциональное веб-приложение «Список покупок».
Основные теоретические положения
Section titled “Основные теоретические положения”1. Что такое Service Worker?
Section titled “1. Что такое Service Worker?”Service Worker — это JavaScript-файл, который работает в фоновом режиме браузера, отдельно от основного потока выполнения веб-страницы. Он действует как программный прокси-сервер между браузером и сетью, позволяя перехватывать сетевые запросы, управлять кэшем и обеспечивать офлайн-функциональность. Service Worker не имеет прямого доступа к DOM, но может взаимодействовать со страницей через механизм обмена сообщениями (postMessage) и события [1].
Жизненный цикл Service Worker:
- Регистрация (Registration): Браузер скачивает и регистрирует файл Service Worker.
- Установка (Installation): Вызывается событие
install. На этом этапе обычно происходит предварительное кэширование статических ресурсов. - Активация (Activation): Вызывается событие
activate. Здесь обычно происходит очистка старых кэшей. - Работа (Fetch/Message): Service Worker готов перехватывать сетевые запросы (событие
fetch) или получать сообщения.
2. Что такое IndexedDB?
Section titled “2. Что такое IndexedDB?”IndexedDB — это встроенная в браузер низкоуровневая объектная база данных для хранения значительных объёмов структурированных данных на стороне клиента. В отличие от localStorage, IndexedDB [2]:
- Поддерживает транзакции для обеспечения целостности данных.
- Позволяет создавать индексы для быстрого поиска.
- Работает асинхронно, не блокируя основной поток выполнения (UI).
- Может хранить сложные объекты JavaScript.
Основные понятия IndexedDB:
- База данных (Database): Контейнер для хранилищ объектов.
- Хранилище объектов (Object Store): Аналог таблиц в реляционных БД.
- Транзакция (Transaction): Оболочка вокруг операций чтения/записи.
- Курсор (Cursor): Механизм для перебора записей в хранилище.
3. Стратегии кэширования
Section titled “3. Стратегии кэширования”При перехвате запросов в Service Worker можно использовать различные стратегии [3]:
- Cache First (Сначала кэш): Идеально для статических ресурсов (картинки, CSS, шрифты).
- Network First (Сначала сеть): Подходит для часто обновляемых данных.
- Stale While Revalidate (Устаревшее при обновлении): Немедленно возвращается кэш, а в фоне идет обновление.
Алгоритм выполнения работы
Section titled “Алгоритм выполнения работы”Выполняйте задания последовательно. Для каждого пункта пишите код и проверяйте его работоспособность в браузере (используйте DevTools: вкладки Console, Application -> Service Workers, Application -> IndexedDB, Application -> Cache Storage).
Часть 1: Создание PWA и офлайн-режима
Section titled “Часть 1: Создание PWA и офлайн-режима”- Подготовка проекта: Создайте папку
pwa_shopping_list/и базовые файлы:index.html,app.js,sw.js,styles.css,manifest.webmanifest,offline.html. Для разработки используйте локальный сервер (например,python3 -m http.server 8000). - Создание Manifest: Заполните
manifest.webmanifest(имя, иконки,start_url,display: standalone) и подключите его кindex.html. - Регистрация Service Worker: В
app.jsзарегистрируйтеsw.js. - Кэширование ресурсов: В
sw.jsна событиеinstallсоздайте кэшshopping-list-cache-v1и добавьте в него все основные файлы приложения, включаяoffline.html. - Очистка старого кэша: На событие
activateудалите все кэши, кромеshopping-list-cache-v1. - Перехват запросов: На событие
fetchреализуйте стратегию Cache First. При ошибке сети для навигационных запросов возвращайте страницуoffline.html. - Индикатор сети: В
app.jsдобавьте слушателиonlineиofflineдля отображения статуса сети на странице.
Часть 2: Локальное хранение и работа со списком (IndexedDB)
Section titled “Часть 2: Локальное хранение и работа со списком (IndexedDB)”- Инициализация БД: В
app.jsнапишите функциюinitDB(), которая открывает базу данныхshopping_list_dbверсии 1. - Создание хранилищ: В обработчике
onupgradeneededсоздайте два хранилища:items(keyPath: 'id', autoIncrement: true) иsyncQueue(autoIncrement: true). Вitemsсоздайте индекс по полюstatus. - CRUD-операции: Реализуйте функции для работы с
items:addItem(item): добавляет товар.getItems(): получает все товары.updateItem(item): обновляет товар (используйте методput).deleteItem(id): удаляет товар.
- Тестовые данные: При первом открытии базы добавьте несколько тестовых товаров.
Часть 3: Интеграция интерфейса и расширенные возможности
Section titled “Часть 3: Интеграция интерфейса и расширенные возможности”- Отображение данных: Напишите функцию
renderItems(items), которая отрисовывает товары на странице. Каждый товар должен иметь название, чекбокс для отметки “Куплено”, кнопку “Редактировать” и кнопку “Удалить”. - Редактирование товара: При нажатии на кнопку “Редактировать” позвольте пользователю изменить название товара (например, через
promptили заменив текст наinput) и сохраните изменения с помощьюupdateItem(). - Поиск/фильтрация: Добавьте на страницу поле
inputдля поиска. При вводе текста фильтруйте отображаемый список товаров в реальном времени. - Массовые операции: Добавьте кнопки “Удалить купленные” и “Отметить все как купленные”, которые выполняют соответствующие действия над списком.
- Проверка офлайн-работы: Убедитесь, что все функции (добавление, редактирование, удаление, поиск) корректно работают в офлайн-режиме.
Часть 4: Имитация фоновой синхронизации (Background Sync)
Section titled “Часть 4: Имитация фоновой синхронизации (Background Sync)”- Логика сохранения: Измените функцию добавления товара. Если
navigator.onLineравноfalse, сохраняйте новый товар не только вitems, но и вsyncQueue. - Синхронизация при появлении сети: В обработчике события
onlineнапишите логику, которая “отправляет” данные изsyncQueueна сервер (имитируйте черезconsole.log), а после “успешной отправки” очищаетsyncQueue. - Индикатор: Добавьте на страницу счетчик “Ожидают синхронизации: N”, который показывает количество записей в
syncQueue.
Часть 5: Администрирование и анализ
Section titled “Часть 5: Администрирование и анализ”- Очистка данных: Добавьте кнопку “Очистить кэш и БД”, которая удаляет базу данных (
indexedDB.deleteDatabase()) и все кэши в Cache Storage, после чего перезагружает страницу. - Анализ производительности: Подготовьте краткий отчёт (в виде Markdown-файла
report.md) о том, как Service Worker влияет на скорость повторной загрузки приложения. Сравните время загрузки с включенным и отключенным SW через вкладку Network в DevTools (показателиDOMContentLoadedиFinish).
Контрольные вопросы
Section titled “Контрольные вопросы”- Что такое Progressive Web App (PWA) и какие его основные преимущества?
- Что такое Service Worker и чем он отличается от обычного JavaScript-кода на странице?
- Какие события жизненного цикла Service Worker вы использовали и зачем они нужны?
- Что такое Cache Storage и как он помогает обеспечить офлайн-доступ к приложению?
- Чем стратегия Cache First отличается от Network First? В каких случаях какую лучше применять?
- Что такое
manifest.webmanifestи для чего он используется в PWA? - Что такое IndexedDB и чем она отличается от
localStorageиsessionStorage? - Как создаётся объектное хранилище в IndexedDB? Что такое
keyPathиautoIncrement? - Зачем нужны транзакции в IndexedDB? Какие режимы транзакций существуют?
- Как работает механизм имитации синхронизации данных, реализованный в Части 4, и почему он важен для офлайн-приложений?
Рекомендуемая литература и ресурсы
Section titled “Рекомендуемая литература и ресурсы”- MDN Web Docs: Service Worker API
- MDN Web Docs: Использование IndexedDB
- web.dev: Service workers and the Cache Storage API
- JavaScript.info: IndexedDB
- Google Developers: The Offline Cookbook (Стратегии кэширования)
- MDN Web Docs: Web App Manifest