强制设置网络超时

有时,您的网络连接速度太慢,或您的网络连接会冒充您在线。在混合使用 Service Worker 的情况下,网络优先的缓存策略可能需要很长时间才能从网络获得响应,或者请求将挂起,并且加载旋转图标会不停地旋转,直到出现错误页面。

无论是什么情况,都存在以下情况:最好在一段时间后回退到某个资源或页面的最后一个缓存响应,但这也是 Workbox 可以帮助解决的另一个问题。

使用 networkTimeoutSeconds

使用 NetworkFirstNetworkOnly 策略时,可以强制网络请求超时。这些策略提供了一个 networkTimeoutSeconds 选项,用于指定 Service Worker 在释放并返回网络响应的最新缓存版本之前,应等待网络响应到达的秒数:

// sw.js
import { NetworkFirst } from 'workbox-strategies';
import { registerRoute, NavigationRoute } from 'workbox-routing';

// Only wait for three seconds before returning the last
// cached version of the requested page.
const navigationRoute = new NavigationRoute(new NetworkFirst({
  networkTimeoutSeconds: 3,
  cacheName: 'navigations'
}));

registerRoute(navigationRoute);

以上代码指示 Service Worker 放弃任何网络优先导航请求,并在三秒后使用上次缓存的版本。当与导航请求结合使用时,这可保证能够访问之前访问过的任何页面的最后一个缓存响应。

但是,如果您所访问的网页在缓存中没有更早的响应,该怎么办?在这种情况下,您可以建立一个针对常规离线 HTML 网页的后备响应:

import {registerRoute, NavigationRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

// Hardcode the fallback cache name and the offline
// HTML fallback's URL for failed responses
const FALLBACK_CACHE_NAME = 'offline-fallback';
const FALLBACK_HTML = '/offline.html';

// Cache the fallback HTML during installation.
self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(FALLBACK_CACHE_NAME).then((cache) => cache.add(FALLBACK_HTML)),
  );
});

// Apply a network-only strategy to navigation requests.
// If offline, or if more than five seconds pass before there's a
// network response, fall back to the cached offline HTML.
const networkWithFallbackStrategy = new NetworkOnly({
  networkTimeoutSeconds: 5,
  plugins: [
    {
      handlerDidError: async () => {
        return await caches.match(FALLBACK_HTML, {
          cacheName: FALLBACK_CACHE_NAME,
        });
      },
    },
  ],
});

// Register the route to handle all navigations.
registerRoute(new NavigationRoute(networkWithFallbackStrategy));

这之所以有效,是因为在 NetworkFirst 策略中使用 networkTimeoutSeconds 时,如果发生超时,并且没有与网址匹配的缓存,处理程序将返回错误响应。如果发生这种情况,handlerDidError Workbox 插件可以提供通用响应作为后备。

等待时间太长?

为请求(尤其是导航请求)强制超时时,您需要在不让用户等待过长和超时过快之间取得适当的平衡。等待时间太长,用户可能会在超时之前遇到连接速度缓慢的问题。超时过快,可能会导致您不必要地从缓存中提供过时的内容。

正确答案是“视情况而定”。如果您运行的是博客之类的网站,且不经常更新内容,那么正确的答案可能是不要等待太多,因为缓存中的任何内容都可能是“全新”就足够了但是,对于交互性更强的网站和 Web 应用,最好再等待一段时间,并避免过早地从 Service Worker 缓存中提供过时数据。

如果您要记录该字段的指标,请查看首字节时间 (TTFB)First Contentful Paint (FCP) 得分的第 75 个百分位,了解用户群中可能有哪些较长的导航请求等待时间。您可以借此深入了解应该如何界定界限。