1

我同时使用 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": [
    "!/**"
  ]
}

我认为服务人员应该“具有普遍意识”,但是如果不是,是否有任何干净的解决方案或解决方法?

4

2 回答 2

1

由于框架不提供此功能,我将其作为功能请求提交,一位团队成员(简而言之)告诉我,客户端在线这一事实并不能保证 SSR 页面的渲染速度会比加载客户端应用程序更快来自缓存,并且由于 SSR 页面引用最新的客户端应用程序,因此可能会破坏更新机制。

有关更多详细信息,请参阅GitHub 问题

于 2019-06-08T14:44:30.617 回答
0

当没有互联网连接时,您需要使用 service worker 为用户提供离线页面

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>
于 2019-06-05T03:50:59.177 回答