强制设置网络超时

有时您的网络连接速度过慢,或您的连接谎称您处于在线状态。在混合使用 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)首次内容绘制 (FCP) 得分的第 75 个百分位,以了解您的用户群中哪些情况下可能会出现导航请求等待时间较长的情况。这可以帮助您弄清楚应该在何处界定界限。