shadowwalker / next-pwa

Zero config PWA plugin for Next.js, with workbox 🧰
MIT License
3.7k stars 312 forks source link

Service Worker make request pending for minutes #200

Open meotimdihia opened 3 years ago

meotimdihia commented 3 years ago

Summary

Service Worker make requests pending for minutes. I have to unregister the service worker to make requests to continue. The problem is related to https://github.com/vercel/next.js/issues/10061

How To Reproduce

The problem happened randomly. I dunno how to reproduce reliably.

Screenshots

image image

davidkaneda commented 3 years ago

@meotimdihia This is probably something else, but something I've run into: Double check if you have "Update on reload" checked in the Chrome Inspector under Application → Service Workers. For me, this makes the size of the local cache (which can be quite large when next-pwa caches the whole public dir proactively) have a huge impact/delay on every network request.

meotimdihia commented 3 years ago

@davidkaneda hi, "update on reload" is unchecked on my browser.

Parnswir commented 3 weeks ago

@meotimdihia did you find out more about this issue in the mean time? We're experiencing this as well (also very randomly).

meotimdihia commented 3 weeks ago

@Parnswir I stopped to use this package. And do it myself:

next.config.js

const { InjectManifest } = require("workbox-webpack-plugin")
const nextConfig = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    if (!isServer && !dev && !process.env.SERVICE_WORKER_DISABLED) {
      config.plugins.push(
        new InjectManifest({
          swSrc: "./sw.ts",
          swDest: "../public/sw.js",
          include: ["__nothing__"]
        })
      )
    }

    return config
  }
}

ws.ts

/// <reference lib="webworker" />
//@ts-ignore
import { registerRoute, setDefaultHandler } from "workbox-routing"
//@ts-ignore
import {
  StaleWhileRevalidate,
  NetworkFirst,
  CacheFirst,
  NetworkOnly
} from "workbox-strategies"
//@ts-ignore
import { skipWaiting, clientsClaim } from "workbox-core"

import { ExpirationPlugin } from "workbox-expiration"
//@ts-ignore
import { precacheAndRoute, matchPrecache } from "workbox-precaching"

skipWaiting()
clientsClaim()

//@ts-ignore
const WB_MANIFEST = self.__WB_MANIFEST
// Precache fallback route and image
WB_MANIFEST.push(
  {
    url: "/offline",
    revision: Math.random().toString(36).substring(7)
  }
  // {
  //   url: "/search",
  //   revision: Math.random().toString(36).substring(7)
  // }
)
const FALLBACK_HTML_URL = "/offline"
precacheAndRoute([FALLBACK_HTML_URL])

registerRoute("/", new NetworkOnly({}), "GET")
registerRoute(
  /^https:\/\/fonts\.(?:googleapis|gstatic)\.com\/.*/i,
  new CacheFirst({
    cacheName: "google-fonts",
    plugins: [
      new ExpirationPlugin({
        maxEntries: 4,
        maxAgeSeconds: 365 * 24 * 60 * 60,
        purgeOnQuotaError: !0
      })
    ]
  }),
  "GET"
)
registerRoute(
  /\.(?:eot|otf|ttc|ttf|woff|woff2|font.css)$/i,
  new CacheFirst({
    cacheName: "static-font-assets",
    plugins: [
      new ExpirationPlugin({
        maxEntries: 4,
        maxAgeSeconds: 604800,
        purgeOnQuotaError: !0
      })
    ]
  }),
  "GET"
)
registerRoute(
  ({ request }) => {
    if (
      request.destination === "image" &&
      (request.url.includes("_next/") || request.url.includes("static/"))
    ) {
      return true
    } else {
      return false
    }
  },
  new StaleWhileRevalidate({
    cacheName: "image-cache",
    plugins: [
      new ExpirationPlugin({
        // Only cache requests for a 3 days
        maxAgeSeconds: 3 * 24 * 60 * 60,
        maxEntries: 100,
        purgeOnQuotaError: !0
      })
    ]
  })
)

registerRoute(
  ({ request }) => {
    if (request.url.includes("_next/static")) {
      return true
    } else {
      return false
    }
  },
  new CacheFirst({
    cacheName: "static-assets",
    plugins: [
      new ExpirationPlugin({
        // Only cache requests for a 1 days
        maxAgeSeconds: 24 * 60 * 60,
        maxEntries: 250,
        purgeOnQuotaError: true
      })
    ]
  })
)

setDefaultHandler(new NetworkOnly())
Parnswir commented 3 weeks ago

Thanks a lot for your reply! That's what I feared would be necessary 🫣