Перейти к содержанию

Что должно работать в офлайн-учебнике

Читатель открыл длинный урок, сел в поезд и потерял сеть. Текст, который уже виден во вкладке, может остаться на экране, но переход к следующей странице способен закончиться ошибкой. Само посещение сайта ещё не означает, что браузер подготовил библиотеку для автономной работы. Для этого нужно определить, что сохранять и как сообщать о доступности.

Начнём проект offline-lab: небольшой учебник из готовых статических страниц. Мы используем знакомые ID xml и markdown, сохраняя их URL. Настоящий ProfessorWeb не становится стендом эксперимента. Опыт его переноса дал принцип постоянных адресов и общих шаблонов; автономные состояния этой серии предстоит получить в собственном учебном проекте.

Задача автономного режима

Офлайн-режим означает, что определённая функция работает без доступного сетевого ответа. Нужно назвать эту функцию точно. В нашем проекте человек выбирает главы, сохраняет их и позже читает текст с необходимыми ресурсами. Он также видит, какие ссылки доступны локально, и может сохранить место продолжения. Это ограниченная понятная задача.

Мы не обещаем автономную работу всех двадцати тысяч страниц. У библиотеки есть изображения, исходники, внешние демонстрации и ссылки на другие сайты. Если документ зависит от сетевого видео или отдельного API, его HTML недостаточно для полного сценария. Сначала составляется набор обязательных ресурсов и объясняются ограничения материала.

Установка приложения и работа без сети — разные результаты. Manifest описывает представление сайта как приложения, а service worker помогает управлять запросами и сохранёнными ответами. Браузер может предложить установку сайта, который не сохранил нужные главы. Поэтому иконка на рабочем столе не является проверкой автономности. Установка PWA, офлайн-работа.

Состояние Что известно Что показать читателю
Глава сохранена полностью Есть документ и обязательные ресурсы Доступна без сети
Загружена часть набора Готовность не подтверждена Сохранение не завершено
Глава не выбрана Локальной копии может не быть Для открытия может понадобиться сеть
Удаление подтверждено сервером Получен соответствующий ответ Материал удалён, а не просто offline

Последняя строка отличается от неизвестной страницы при отсутствии сети. Без ответа сервера нельзя узнать, существует ли адрес сейчас. Если приложение показывает всем таким переходам «404», оно придумывает состояние сервера. Позже мы построим отдельное сообщение о недоступности и сохраним настоящий сетевой ответ для известного отсутствующего документа.

Документы и постоянные адреса

В реестре xml означает /my/LINQ/linq_xml/level7/7_1.php, а markdown — /articles/markdown-guide.html. Первый путь взят из прежней библиотеки ProfessorWeb; короткие тексты в учебных исходниках служат демонстрации. Они не заменяют полные оригинальные статьи. Реестр позволяет сохранять личность документа при изменении названия и оформления.

Расширение .php не делает нашу страницу серверной программой. В учебном проекте сервер должен выдавать готовый HTML с правильным MIME, как обсуждалось в Markdown-курсе. Service worker не исправляет неправильную серверную настройку. Если браузер получает файл для скачивания вместо HTML, нужно исследовать ответ, а не объявлять адрес сохранённой главой.

Создадим отдельный origin для практики: свой локальный сервер или собственное тестовое окружение. Работа на localhost позволяет изучать API в подходящем контексте. Открытие файла двойным щелчком не воспроизводит тот же процесс регистрации и запросов. Протокол, host и порт входят в границы origin, поэтому смена порта может означать другое хранилище.

Рядом с готовыми страницами будут index.html, offline.html, manifest.webmanifest, sw.js, папка assets и data/documents.json. Главная содержит список двух глав, запасная страница объясняет недоступность, manifest описывает приложение, а worker постепенно добавит обработку запросов. Генератор Markdown здесь не создаётся повторно: мы используем уже полученные документы.

Что хранится в браузере

Cache API сохраняет пары запросов и ответов. Для главы нужен именно ответ с HTML, а не строка её названия. Позднее для закладок понадобится отдельное структурированное хранилище: ID материала, раздел и выбранные настройки. Смешивать эти данные необязательно; разные задачи имеют разные формы и правила обновления.

Кеш приложения не равен обычному HTTP-кешу браузера. HTTP-кеш управляется сетевыми правилами, а Cache API предоставляет программе явные операции хранения. Наличие ресурса в одном месте не гарантирует, что наша логика найдёт его в другом. Поэтому «я уже открывал страницу» и «приложение подтвердило её сохранение» должны оставаться разными утверждениями.

Браузерное хранилище имеет ограничения и может быть очищено. Пользователь способен удалить данные сайта, а платформа — вытеснить их при определённых условиях. Автономный учебник должен учитывать потерю локальной копии и предлагать восстановление, когда сеть появится. Он не заменяет архив исходников и резервные копии проекта. Cache API, квоты и вытеснение.

Место поиска

Поиск в готовой библиотеке — отдельный компонент. В этой серии мы не строим новый индекс и не повторяем ранжирование. Если используется браузерный поиск с локальными данными, приложение должно объяснять, какие найденные документы фактически сохранены. Результат поиска и доступность его назначения — разные сведения.

Если поиск требует сервера, автономный режим не делает его автоматически локальным. Можно оставить список выбранных глав как доступный способ навигации и явно показать ограничение сетевого компонента. Не выдавайте пустой ответ из-за отсутствия сети за отсутствие материалов по запросу. Это та же граница между состоянием данных и состоянием доставки.

В поисковом курсе Web Worker переносил вычисления из основного потока. Service worker этой серии имеет другой жизненный цикл и назначение: он может обрабатывать запросы управляемых страниц. Нельзя заменить один другим только из-за слова worker в названии. Их взаимодействие будет ограничено готовым компонентом и договором доступности.

Учебный результат

Сохраните короткую заметку: две главы, обязательные ресурсы, условия origin, поведение несохранённой ссылки и ограничения поиска. Для каждой возможности нужен будущий наблюдаемый результат. Например, после явного сохранения XML его точный URL должен открываться без сети; после прерванной загрузки интерфейс не должен показывать полную готовность.

Такое описание направляет следующие уроки. Сначала добавим manifest, затем изучим регистрацию и жизненный цикл worker, а после сохраним одну страницу. Более сложные задачи — согласованность версий, закладки и восстановление — появятся на известной основе. Мы начинаем с маленького набора, который можно объяснить вручную, а рост библиотеки будет опираться на явный выбор и ограничения хранения.