Сервисный работник делает мою сеть медленнее! , как добавить офлайн-возможности в работу Django с помощью workbox

Я уже несколько дней пытаюсь предоставить офлайн-возможности, используя workbox для моего Django Web Приложение безуспешно.

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

Код, сделанный для архивации описания:

urls.py

...
url(r'^service-worker.js', cache_control(max_age=60*60*24)(TemplateView.as_view(
    template_name="sw.js",
    content_type='application/javascript',
)), name='sw.js'),
...

base.html шаблон

...
<!-- bottom of body -->
<script>

  // Check that service workers are registered
        if ('serviceWorker' in navigator) {
          // Use the window load event to keep the page load performant
          window.addEventListener('load', () => {
            navigator.serviceWorker.register('{% url 'sw.js' %}');
          });
        }

</script>
...

sw.js (сервисный работник)

importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.2.0/workbox-sw.js');

if (workbox) {
  console.log(`Yay! Workbox is loaded ????`);
} else {
  console.log(`Boo! Workbox didn't load ????`);
}

workbox.setConfig({
  debug: false
});

// workbox.core.setLogLevel(workbox.core.LOG_LEVELS.debug);


workbox.routing.registerRoute(
  /\.(?:js|css)$/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: 'static-resources',
  }),
);

workbox.routing.registerRoute(
  /\.(?:png|gif|jpg|jpeg|svg)$/,
  workbox.strategies.cacheFirst({
    cacheName: 'images',
    plugins: [
      new workbox.expiration.Plugin({
        maxEntries: 60,
        maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
      }),
    ],
  }),
);

workbox.routing.registerRoute(
  new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
  workbox.strategies.cacheFirst({
    cacheName: 'googleapis',
    plugins: [
      new workbox.expiration.Plugin({
        maxEntries: 30,
      }),
    ],
  }),
);

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

Я оставляю здесь 2 скриншота для проверки (время загрузки показано красным справа внизу):

516 м без обслуживающего работника, с кешем django по умолчанию  введите описание изображения здесь

1.09 с, когда сервис-воркер обслуживает файлы кеша  введите описание изображения здесь

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

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

Но с другой стороны, я подумал, что 500 мс ~, если я получу офлайн-возможности, это справедливая цена, но даже не ...

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

workbox.precaching.precacheAndRoute(
  [
    '/',
    '/offline',
  ],
  {
    directoryIndex: null,
  }
);

workbox.routing.registerRoute(
  /* my urls doesn't end in html, so i didn't found another way to 
  store only the html document except using the main route of my app as reg ex

example: http://localhost:8000/participation/id/title -> html for article
         http://localhost:8000/participation/ -> html for list of articles */

      new RegExp('participation/'), 
      workbox.strategies.networkFirst({
        cacheName: 'html-resources',
      })
    );

Итак, теперь, если я был оффлайн на некоторых страницах участия, я все еще мог их видеть, но это привело меня к моей реальной проблеме.

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

Я не нашел способа решить эту проблему, пробую вот что:

workbox.routing.registerRoute(
  ({ event }) => event.request.mode === 'navigate', //if the requests is to go to a new url
  ({ url }) => fetch(url.href,{credentials: 'same-origin'}).catch(() => caches.match('/offline')) //in case of not match send my to the offline page
);

Но это вообще не работает, как я мог это сделать?


person Roberto Fernandez Diaz    schedule 18.06.2018    source источник


Ответы (1)


Я решил проблему, добавив это в сервис-воркер

// Fallback to offline page if nothing is found in cache
var networkFirstHandler = workbox.strategies.networkFirst({
  cacheName: 'default',
  plugins: [
    new workbox.expiration.Plugin({
      maxEntries: 10
    }),
    new workbox.cacheableResponse.Plugin({
      statuses: [200]
    })
  ]
});

const matcher = ({event}) => event.request.mode === 'navigate';
const handler = (args) => networkFirstHandler.handle(args).then((response) => (!response) ? caches.match('/offline') : response);

workbox.routing.registerRoute(matcher, handler);
// End fallback offline
person Roberto Fernandez Diaz    schedule 19.06.2018
comment
Спасибо, что разместили свое решение. Похоже, что в Workbox 4 будет собственное решение этой проблемы. - person Ñhosko; 05.11.2018