Улучшение загрузки страницы PWA - PullRequest
0 голосов
/ 05 января 2019

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

У меня вопрос: какие методы я могу использовать, чтобы улучшить загрузку страницы, при этом сохраняя автономную работу?

У меня может быть минимальная начальная страница (например, просто отобразить сообщение «Пожалуйста, подождите, загружается текст»), а затем динамически загрузить (с помощью встроенного тега сценария или AJAX) файл данных JSON. Тем не менее, я не уверен, каким образом я мог бы впоследствии обеспечить получение данных из кэша.

Просто интересно, как другие справились с этой проблемой ...

1 Ответ

0 голосов
/ 30 июня 2019

Поскольку этот вопрос перевалил, я решил опубликовать результаты своих попыток.

Основываясь на статье Джейка , я использовал следующий скрипт и Chrome DevTools для изучения событий работника сервиса:

'use strict';

let container = null;
let updateFound = false;
let newInstall = false;

window.onload = () => {
  container = document.querySelector('.container');
  let loading = document.createElement('div');
  loading.classList.add('loading');
  loading.innerHTML = 'Downloading application.<br>Please wait...';
  container.appendChild(loading);
  console.log(`window.onload:      ${Date.now()}`);
  swEvents();
};

let swEvents = () => {
  if (navigator.serviceWorker) {
    navigator.serviceWorker.ready.then(() => {
      console.log(`sw.ready:           ${Date.now()}`);
      if (!updateFound) {
        loadApp();
        return;
      }
      newInstall = true;
      console.log(`new install:        ${Date.now()}`);
    }).catch((error) => {
      console.log(`sw.ready error: ${error.message}`);
    });
  }

  navigator.serviceWorker.register('/sw.js').then((reg) => {
    reg.onupdatefound = () => {
      updateFound = true;
      console.log(`reg.updatefound:    ${Date.now()}`);
      const newWorker = reg.installing;
      newWorker.onstatechange = (event) => {
        if (event.target.state === 'activated') {
          console.log(`nw.activated:       ${Date.now()}`);
          if (newInstall) {
            loadApp();
            return;
          }
          refresh();
        }
      };
    };
  }).catch((error) => {
    console.log(`reg.error: ${error.message}`);
  });
};

let refresh = () => {
  console.log(`refresh():          ${Date.now()}`);
  // window.location.reload(true);
};

let loadApp = () => {
  console.log(`loadApp():          ${Date.now()}`);
  let child;
  while (child = container.firstChild) {
    container.removeChild(child);
  }
  let message = document.createComment('p');
  message.textContent = 'Application loading';
  container.appendChild(message);
  let tag = document.createElement('script');
  tag.src = './app.js';
  document.body.appendChild(tag);
};

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

Для новой установки в вышеуказанном сценарии регистрируются следующие события:

window.onload -> reg.updatefound -> sw.ready -> nw.activated

В этом случае, когда срабатывает sw.ready, все ресурсы были кэшированы. На этом этапе я могу переключить приложение из фазы «пожалуйста, подождите», динамически загружать кэшированные ресурсы и запускать приложение.

Для простого обновления страницы регистрируются следующие события:

window.onload -> sw.ready

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

Для обновления страницы после обновления сценария работника службы регистрируются следующие события:

window.onload -> sw.ready -> reg.updatefound -> nw.activated

В этом случае при срабатывании nw.activated все кэшированные ресурсы были обновлены. Другое обновление страницы требуется для фактической загрузки изменений. На этом этапе пользователю может быть предложено обновить. Или приложение будет обновляться самостоятельно при следующем запуске.

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

...