Как использовать страницы SSR при подключении к Интернету и переход на кешированный index.html при работе в автономном режиме - PullRequest
1 голос
/ 05 июня 2019

Я использую Angular PWA и Angular Universal одновременно и играю с автономной навигацией.

Поведение, которое я пытаюсь реализовать для запросов навигации:

  • Когда он-лайн, обслуживайте страницы, отображаемые на стороне сервера, для максимальной первой скорости рисования (затем на стороне клиента)
  • В автономном режиме откат к кэшированному index.html для использования кэшированного клиентского приложения

Проблема в том, что ngsw-worker.js и его файл конфигурации ngsw-config.json не обеспечивают достаточно высокий уровень детализации для достижения этого.

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

{
  "index": "/index.html",
  "assetGroups": [
    {
      "name": "app",
      "installMode": "prefetch",
      "resources": {
        "files": [
          "/favicon.ico",
          "/index.html",
          "/*.css",
          "/*.js"
        ]
      }
    },
    {
      "name": "assets",
      "installMode": "lazy",
      "updateMode": "prefetch",
      "resources": {
        "files": [
          "/assets/**",
          "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)"
        ]
      }
    }
  ],
  "dataGroups": [
    {
      "name": "backend",
      "urls": [
        "/backend/**"
      ],
      "cacheConfig": {
        "maxSize": 100,
        "maxAge": "3d",
        "strategy": "freshness"
      }
    },
    {
      "name": "serverSideRenderedPages",
      "urls": [
        "/**"
      ],
      "cacheConfig": {
        "maxSize": 100,
        "maxAge": "3d",
        "strategy": "freshness"
      }
    }
  ],
  "navigationUrls": [
    "!/**"
  ]
}

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

Ответы [ 2 ]

1 голос
/ 08 июня 2019

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

Подробнее см. GitHub .

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

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

const cacheName = 'cache-v1';
const offlineUrl = 'offline-page.html';

// Cache our known resources during install
self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(cacheName)
    .then(cache => cache.addAll([
      './index.html',
      offlineUrl
    ]))
  );
});

// Cache any new resources as they are fetched
self.addEventListener('fetch', function(event) {
    event.respondWith(
      caches.match(event.request)
      .then(function(response) {
        if (response) {
          return response;
        }
        var fetchRequest = event.request.clone();

        return fetch(fetchRequest).then(
          function(response) {
            if(!response || response.status !== 200) {
              return response;
            }

            var responseToCache = response.clone();
            caches.open(cacheName)
            .then(function(cache) {
              cache.put(event.request, responseToCache);
            });

            return response;
          }
        ).catch(error => {
          // Check if the user is offline first and is trying to navigate to a web page. If user navigate to another page the website will serve them the offline page
          if (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html')) {
          // Return the offline page
          return caches.match(offlineUrl);
        }
        });
      })
    );
});

Затем поместите этот скрипт в ваш index.html

  <script>
  // Register the service worker
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('./sw.js').then(function(registration) {
      // Registration was successful
    });
  }
  </script>
...