Общей архитектурной особенностью одностраничных веб-приложений (SPA) является минимальный набор HTML, CSS и JavaScript, необходимый для обеспечения глобальной функциональности приложения. На практике это обычно заголовок, навигация и другие общие элементы пользовательского интерфейса, которые сохраняются на всех страницах. Когда сервисный работник предварительно кэширует HTML-код и зависимые ресурсы этого минимального пользовательского интерфейса, мы называем это оболочкой приложения .
Оболочка приложения играет важную роль в воспринимаемой производительности веб-приложения. Это первое, что загружается, и, следовательно, это также первое, что видят пользователи, пока они ждут, пока контент заполнит пользовательский интерфейс.
Хотя оболочка приложения загружается быстро (при условии, что сеть доступна и хотя бы немного быстрее), сервис-воркер, который пр��дварительно кэширует оболочку приложения и связанные с ней ресурсы, дает модели оболочки приложения следующие дополнительные преимущества:
- Надежная и стабильная работа при повторных посещениях. При первом посещении приложения без установленного сервис-воркера разметка приложения и связанные с ним ресурсы должны быть загружены из сети, прежде чем сервис-воркер сможет поместить их в свой кэш. Однако повторные посещения будут извлекать оболочку приложения из кеша, а это означает, что загрузка и рендеринг будут мгновенными.
- Надежный доступ к функциям в автономных сценариях. Иногда доступ в Интернет нерегулярный или вообще отсутствует, и появляется ужасный экран «мы не можем найти этот веб-сайт». Модель оболочки приложения решает эту проблему, отвечая на любой запрос навигации разметкой оболочки приложения из кэша. Даже если кто-то посетит URL-адрес в вашем веб-приложении, на котором он никогда раньше не был, оболочка приложения будет обслуживаться из кэша и может быть заполнена полезным контентом.
Когда следует использовать модель оболочки приложения
Оболочка приложения имеет наибольший смысл, когда у вас есть общие элементы пользовательского интерфейса, которые не меняются от маршрута к маршруту, но меняется содержимое. Большинство SPA, скорее всего, уже используют модель оболочки приложения.
Если это описывает ваш проект и вы хотите добавить сервисного работника для повышения его надежности и производительности, оболочка приложения должна:
- Загружайтесь быстро .
- Используйте статические ресурсы из экземпляра
Cache
. - Включите общие элементы интерфейса, такие как заголовок и боковая панель, отдельно от содержимого страницы.
- Извлечение и отображение содержимого конкретной страницы.
- При необходимости кэшируйте динамический контент для просмотра в автономном режиме.
Оболочка приложения динамически загружает содержимое конкретной страницы через API или содержимое, встроенное в JavaScript. Он также должен быть самообновляющимся в том смысле, что если разметк�� ��болочк�� пр��ложения ��з��енит��я, обновление сервисного работника должно подобрать новую оболочку приложения и автоматически кэшировать ее.
Создание оболочки приложения
Оболочка приложения должна существовать независимо от контента, но при этом обеспечивать основу для размещения в нем контента. В идеале он должен быть как можно более компактным, но при первоначальной загрузке включать достаточно значимого контента, чтобы пользователь понимал, что контент загружает��я быстро.
Правильный баланс зависит от вашего приложения. Оболочка приложения Trained To Thrill Джейка Арчибальда включает заголовок с кнопкой обновления для получения нового контента с Flickr.
Разметка оболочки приложения будет варьироваться от проекта к проекту, но вот один пример файла index.html
, который предоставляет шаблон приложения:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>
Application Shell Example
</title>
<link rel="manifest" href="/manifest.json">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="styles/global.css">
</head>
<body>
<header class="header">
<!-- Application header -->
<h1 class="header__title">Application Shell Example</h1>
</header>
<nav class="nav">
<!-- Navigation items -->
</nav>
<main id="app">
<!-- Where the application content populates -->
</main>
<div class="loader">
<!-- Spinner/content placeholders -->
</div>
<!-- Critical application shell logic -->
<script src="app.js"></script>
<!-- Service worker registration script -->
<script>
if ('serviceWorker' in navigator) {
// Register a service worker after the load event
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js');
});
}
</script>
</body>
</html>
Как бы вы ни создавали оболочку приложения для своего проекта, она должна иметь следующие характеристики:
- HTML должен иметь четко изолированные области для отдельных элементов пользовательского интерфейса. В приведенном выше примере это включает заголовок приложения, навигацию, область основного содержимого и место для «спиннера» загрузки, который появляется только при загрузке содержимого.
- Исходный код JavaScript и CSS, загружаемый для оболочки приложения, должен быть минимальным и относиться только к функциональности самой оболочки приложения, а не к содержимому. Это гарантирует, что приложение отображает свою оболочку как можно быстрее и сводит к минимуму работу основного потока до тех пор, пока не появится содержимое.
- Встроенный скрипт, который регистрирует сервисного работника.
После создания оболочки приложения вы можете создать сервис-воркер для кэширования как самой оболочки, так и ее ресурсов.
Кэширование оболочки приложения
Оболочка приложения и ее необходимые ресурсы — это то, что сервисный работник должен предварительно кэшировать сразу во время установки. Предположим, что оболочка приложения подобна приведенному выше примеру, давайте посмотрим, как это можно сделать в базовом примере Workbox с помощью workbox-build
:
// build-sw.js
import {generateSW} from 'workbox-build';
// Where the generated service worker will be written to:
const swDest = './dist/sw.js';
generateSW({
swDest,
globDirectory: './dist',
globPatterns: [
// The necessary CSS and JS for the app shell
'**/*.js',
'**/*.css',
// The app shell itself
'shell.html'
],
// All navigations for URLs not precached will use this HTML
navigateFallback: 'shell.html'
}).then(({count, size}) => {
console.log(`Generated ${swDest}, which precaches ${count} assets totaling ${size} bytes.`);
});
Эта конфигурация, хранящаяся в build-sw.js
импортирует CSS и JavaScript приложения, включая файл разметки оболочки приложения, содержащийся в shell.html
. Скрипт выполняется с помощью Node следующим образом:
node build-sw.js
Созданный сервис-воркер записывается в ./dist/sw.js
и по завершении записывает следующее сообщение:
Generated ./dist/sw.js, which precaches 5 assets totaling 44375 bytes.
Когда страница загружается, сервис-воркер предварительно кэширует разметку оболочки приложения и ее зависимости:
![Снимок экрана сетевой панели в Chrome DevTools, показывающий список ресурсов, загруженных из сети. Ресурсы, предварительно кэшированные сервисным работником, отличаются от других активов шестеренкой слева в строке. Некоторые файлы JavaScript и CSS предварительно кэшируются сервисным работником во время установки.](https://cdn.statically.io/img/developer.chrome.google.cn/static/docs/workbox/app-shell-model/image/a-screenshot-the-network-96ad6896c678b.png?hl=ru)
Предварительное кэширование HTML, CSS и JavaScript оболочки вашего приложения возможно практически в любом рабочем процессе, включая проекты, использующие сборщики. По мере изучения документации вы узнаете, как напрямую использовать Workbox для настройки цепочки инструментов для создания сервис-воркера, который лучше всего подходит для вашего проекта, независимо от того, является ли это SPA.
Заключение
Сочетание модели оболочки приложения с сервис-воркером отлично подходит для автономного кэширования, особенно если вы сочетаете его функцию предварительного кэширования с сетевой стратегией возврата к кэшированию для разметки или ответов API. Результатом является надежно быстрая работа, которая мгновенно отображает оболочку вашего приложения при повторных посещениях, даже в офлайн-условиях.