Рубрики
Без рубрики

Как я сделал свой сайт на основе CMS в автономном режиме

Заинтересованы в изучении JavaScript? Получите мою книгу на jshandbook.comЭта, это исследование, объясняет, как я добавил возможность работать в автономном режиме на веб-сайте writesoftware.org (который основан на Gravious, отличном PHP CMS для разработчиков). Я сделал это, введя набор технологий, сгруппированных под названием

Автор оригинала: FreeCodeCamp Community Member.

Это исследование объясняет, как я добавил возможность работать в автономном режиме для writesoftware.org Веб-сайт (который основан на Gravious, отличный CMS на базе PHP для разработчиков ). Я сделал это, введя набор технологий, сгруппированных под названием Прогрессивные веб-приложения (в частности Сервисные работники и Cache API ).

Я покажу варианты, которые я имел в наличии, и почему я выбрал один подход над другими.

Когда мы закончим, мы сможем использовать наш сайт на мобильном устройстве или на настольном браузере – даже если в автономном режиме – как я показал здесь:

Первый подход: кэш-первый

Сначала я подходил к задаче, используя кэш-первый подход: когда мы перехватываем запрос на выбор в сервисском работнике, мы сначала проверьте, если у нас уже это кэшируется Отказ Если нет, Мы принесем это от сети Отказ

Это имеет преимущество изготовления сайта Продувая быстро При загрузке страниц уже кэшированы, даже когда онлайн – в частности, с медленными сетями и lie-fi Отказ B UT Это также вводит некоторые сложность Управлять обновлениями к кэше, когда я отправляю новый контент.

Это не будет окончательным решением, которое я принимаю , но стоит пройти через его демонстрационные цели.

Я пройду через пару фаз:

  1. Я Представьте работника услуг и загрузить его с помощью сценария JS
  2. При установке сервисного работника я кэш сайта скелет
  3. Я Запросы на сетевой перехваты собирается на дополнительные ссылки и кэшировать их

Представляем сервисный работник

Я добавляю обслуживающий работник в SW.JS Файл в сайте root. Это дает достаточно возможности работать на всех подпапках сайта, а также на сайте дома ( больше на Сервис рабочих возможностей здесь ). SW на данный момент довольно базовый, так как он просто регистрирует любой запрос сети:

Мне нужно зарегистрировать сервисский работник, и я делаю это из сценария, который я включаю в каждой странице:

Если бы обслуживаемые работники доступны, мы регистрируем SW.JS файл, а в следующий раз я обновляю страницу, она должна работать нормально:

На данный момент мне нужно сделать тяжелый подъем на сайте. Прежде всего, мне нужно придумать способ служить только Приложение Shell : Базовый набор HTML + CSS и JS, который всегда будет доступен и показан пользователями, даже если в автономном режиме.

Это в основном разбитая версия сайта, с

Пустой элемент, который мы заполним контент позже, доступны Энде R The/Shell Route:

Поэтому в первый раз, когда пользователь загружает сайт, будет показана обычная версия страницы (Full-HTML-версия), а также Установлен сервисский работник Отказ

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

Как?

Мы слушаем Установить Событие, которое зажигает, когда работник службы установлен или обновляется. Когда это произойдет, мы инициализируем кэш с содержанием нашей оболочки: базовый HTML-макет, плюс некоторые CSS, JS и некоторые внешние активы:

Затем, когда мы выполняем выборку, мы перехватываем запросы на наши страницы, а Получите оболочку из кэша вместо того, чтобы идти в сеть Отказ

Если URL-адрес принадлежит Google Analytics или Convertkit, я избегаю использовать локальный кеш, и я принесу их без использования CORS (Поскольку мне не разрешено получать доступ к ним через этот метод).

Затем, если я запрашиваю Местный частичный (Просто содержимое страницы, а не полная страница), я просто выдаю запрос для получения.

Если это не частично, Мы возвращаем оболочку , что это уже кэшировано Когда работник службы сначала установлен.

Как только привлечение сделано, я его кэш.

Теперь я редактирую Script.js Файл, чтобы представить важную особенность: всякий раз, когда ссылка на мои страницах, я перехваю его, и я выдаю сообщение для Вещательный канал Отказ

Поскольку обслуживающие работники в настоящее время поддерживаются только в Chrome, Firefox, и Opera, я могу безопасно полагаться на BroadcastChannel API за это.

Сначала я подключаюсь к WS_NAVIGAL Канал, и я приложу OnMessage Обработчик событий на нем. Всякий раз, когда я получаю событие, это общение от обслуживающего работника с новым контентом, чтобы показать внутри приложенной оболочки. Так что я просто смотрю элемент с ID Контент-обертка и поставьте в него частичный контент страницы, эффективно меняя страницу, который виден пользователь.

Как только обслуживание зарегистрировано, Я выдаю сообщение этому каналу с Fetchpartial Задача и Частичная страница URL для получения Отказ Это содержимое нагрузки на начальную страницу.

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

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

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

Теперь мы просто пропустили, чтобы справиться с этим событием. На стороне сервисного работника я подключаюсь к WS_NAVIGAL канал и слушать событие. Я слушаю Fetchpartial Название задачи сообщения, хотя я мог просто избежать этого состояния, так как это единственное событие, которое отправляется здесь. Обратите внимание, что сообщения в API трансляции Channel не отправляются на той же странице, которая их исходит – Они отправлены только между страницей и веб-рабочим.

Я проверяю, кешируется ли URL Отказ Если это так, я просто отправляю его в качестве ответного сообщения на канале и вернуть.

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

Мы почти закончили.

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

И – все это Прогрессивное улучшение Отказ Старые браузеры и браузеры, которые не поддерживают работников службы, просто работают как обычно.

Теперь угнать браузер навигацию представляет несколько проблем:

  1. URL должен изменить Когда появится новая страница. Назад кнопка должна работать нормально, а история браузера также.
  2. Название страницы должно меняться Чтобы отразить заголовок новой страницы.
  3. Нам нужно Уведомить API Google Analytics Эта новая страница была загружена, чтобы избежать отсутствия важной метрики, такой как просмотры страниц на каждого посетителя.
  4. Кодовые фрагменты не выделены больше при загрузке нового контента динамически.

Давайте решим эти задачи.

Исправить URL, заголовок и кнопку обратно с API истории

В дополнение к инъекции HTML частичного в обработчике сообщений в Script.js мы запускаем история. Pushstate () Метод:

Это работает, но заголовок страницы не меняется в браузере UI. Нам нужно получить его как-то со страницы. Я решил поставить скрытый пролет в частичном содержимом страницы, который сохраняет название страницы. Затем мы можем получить его со страницы, используя DOM API и установить Document.title имущество:

Исправить Google Analytics

Google Analytics работает отлично из коробки, но при динамично загрузке страницы не может делать чудеса. Мы должны использовать API, который он предоставляет, чтобы сообщить о новой нагрузке страницы. Поскольку я использую глобальный тег сайта ( GTAG.JS ) Отслеживание, мне нужно позвонить:

в код выше, который обрабатывает изменение страницы:

Что если … пользователь вне форума? В идеале должно быть извлекать Слушатель событий, который кэширует любой запрос на Google Analytics и повторить их, как только я снова в сети.

К счастью, Есть библиотека, которая имеет именно это , полагаясь на IndexedDB для хранения данных. Это было Перемещен в Workbox Если вы предпочитаете использовать эту библиотеку, чтобы обрабатывать кэширование на более высоком уровне.

Исправить синтаксис выделения

Последнее, что мне нужно исправить на моей странице, – это выделение логин фрагментов кода. Я использую синтаксис призмы, и они делают его очень легко – мне просто нужно добавить звонок Prism.Highlightall () В моем OnMessage Обработчик:

Полный код Script.js является:

и SW.JS:

Второй подход: сеть – сначала, отбросьте приложение Shell

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

Если сетевой вызов не удается по какой-то причине, я смотрю на страницу в кэш, чтобы увидеть, если мы получим его кэшированным. В противном случае я показываю пользователю GIF, если он полностью оффлайн, или другой GIF, если страница не существует (я могу достичь ее, но у меня есть ошибка 404).

Как только мы получим страницу, мы кэшируем ее (не проверяя, если мы кэшируем это ранее или нет, мы просто храним последнюю версию).

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

Для этого я только что разделил приложение Shell из Установить Мероприятие обслуживания работника. Я полагался на сервисных работников и Cache API для доставки всего лишь простых страниц сайта, не управляя частичными обновлениями. Я также бросил /оболочка привлечь угон при загрузке полной страницы. На первой загрузке страницы нет задержки, но мы все еще загружаем частиц при навигации на другие страницы позже.

Я все еще использую Script.js и SW.JS провести код, с Script.js Быть файлом, который инициализирует обслуживающий работник, а также перехватывает клики на стороне клиента.

Вот Script.js :

И вот SW.JS :

Третий подход: сбой проще без парциалов вообще

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

Script.js :

SW.JS :

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

То, что я закончил реализовать на моем сайте

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

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