Сервисные работники и модель оболочки приложения

Общей архитектурной особенностью одностраничных веб-приложений (SPA) является минимальный набор HTML, CSS и JavaScript, необходимый для обеспечения глобальной функциональности приложения. На практике это обычно заголовок, навигация и другие общие элементы пользовательского интерфейса, которые сохраняются на всех страницах. Когда сервисный работник предварительно кэширует HTML-код и зависимые ресурсы этого минимального пользовательского интерфейса, мы называем это оболочкой приложения .

Схема оболочки приложения. Это снимок экрана веб-страницы с заголовком вверху и областью содержимого внизу. Заголовок помечен как «Оболочка приложения», а нижний — как «Содержимое».

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

Хотя оболочка приложения загружается быстро (при условии, что сеть доступна и хотя бы немного быстрее), сервис-воркер, который предварительно кэширует оболочку приложения и связанные с ней ресурсы, дает модели оболочки приложения следующие дополнительные преимущества:

  • Надежная и стабильная работа при повторных посещениях. При первом посещении приложения без установленного сервис-воркера разметка приложения и связанные с ним ресурсы должны быть загружены из сети, прежде чем сервис-воркер сможет поместить их в свой кэш. Однако повторные посещения будут извлекать оболочку приложения из кеша, а это означает, что загрузка и рендеринг будут мгновенными.
  • Надежный доступ к функциям в автономных сценариях. Иногда доступ в Интернет нерегулярный или вообще отсутствует, и появляется ужасный экран «мы не можем найти этот веб-сайт». Модель оболочки приложения решает эту проблему, отвечая на любой запрос навигации разметкой оболочки приложения из кэша. Даже если кто-то посетит URL-адрес в вашем веб-приложении, на котором он никогда раньше не был, оболочка приложения будет обслуживаться из кэша и может быть заполнена полезным контентом.

Когда следует использовать модель оболочки приложения

Оболочка приложения имеет наибольший смысл, когда у вас есть общие элементы пользовательского интерфейса, которые не меняются от маршрута к маршруту, но меняется содержимое. Большинство SPA, скорее всего, уже используют модель оболочки приложения.

Если это описывает ваш проект и вы хотите добавить сервисного работника для повышения его надежности и производительности, оболочка приложения должна:

  • Загружайтесь быстро .
  • Используйте статические ресурсы из экземпляра Cache .
  • Включите общие элементы интерфейса, такие как заголовок и боковая панель, отдельно от содержимого страницы.
  • Извлечение и отображение содержимого конкретной страницы.
  • При необходимости кэшируйте динамический контент для просмотра в автономном режиме.

Оболочка приложения динамически загружает содержимое конкретной страницы через API или содержимое, встроенное в JavaScript. Он также должен быть самообновляющимся в том смысле, что если разметка оболочки приложения изменится, обновление сервисного работника должно подобрать новую оболочку приложения и автоматически кэшировать ее.

Создание оболочки приложения

Оболочка приложения должна существовать независимо от контента, но при этом обеспечивать основу для размещения в нем контента. В идеале он должен быть как можно более компактным, но при первоначальной загрузке включать достаточно значимого контента, чтобы пользователь понимал, что контент загружается быстро.

Правильный баланс зависит от вашего приложения. Оболочка приложения Trained To Thrill Джейка Арчибальда включает заголовок с кнопкой обновления для получения нового контента с Flickr.

Снимок экрана веб-приложения Trained to Thrill в двух разных состояниях. Слева видна только оболочка кэшированного приложения без заполнения содержимого. Справа контент (несколько изображений некоторых поездов) динамически загружается в область содержимого оболочки приложения.

Разметка оболочки приложения будет варьироваться от проекта к проекту, но вот один пример файла 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 предварительно кэшируются сервисным работником во время установки.
Service Worker предварительно кэширует зависимости оболочки приложения во время установки. Запросы предварительного кэширования — это последние две строки, а значок шестеренки рядом с запросом указывает, что сервисный работник обработал запрос.

Предварительное кэширование HTML, CSS и JavaScript оболочки вашего приложения возможно практически в любом рабочем процессе, включая проекты, использующие сборщики. По мере изучения документации вы узнаете, как напрямую использовать Workbox для настройки цепочки инструментов для создания сервис-воркера, который лучше всего подходит для вашего проекта, независимо от того, является ли это SPA.

Заключение

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