next-offline
next-offline copied to clipboard
Service Worker aggressive caching makes web app slower
Time-to-Interactive / First CPU Idle / First Input Delay result decrease adding next-offline
service worker to a web app. As can be seen in the screenshots, seems that the service worker is too aggressive caching JS chunks of the web app and makes this results worse.
-
Issue and steps to reproduce: Add to a
next.js
web appnext-offline
using the getting started gide. -
Versions.
-
next.js: 9.2.2
-
next-offline: 5.0.0
-
-
Screenshots.
- Lighthouse without SW.
- Network without SW.
- Lighthouse with SW (15 points of drop! T-t-I from 6.4 to 9.1 seconds, FCI from 5.7 to 7.7 seconds and FID from 580 to 840 ms)
- Network with SW part 1 (we can see the start of all JS of the web app downloading)
- Network with SW part 2.
- Lighthouse without SW.
-
Expected: Same or even better Time-to-Interactive result.
-
Actual: Worse Time-to-Interactive result.
-
Link to your project: https://tentu.eus
-
Browser name and version: Chrome 80
Interesting, this issue might be better suited for the library next-offline is using under the hood
https://github.com/GoogleChrome/workbox
They're really receptive, we can keep this open and you can link the new issue to this one if you'd like
I have being digging a little more and when a build is generated there is a list of *.js
assets that seems to precache when entering the page (I'm checking .next/service-worker.js
after generating a build)
The list looks like this one:
[
// BASE FILES START
{
url: "_next/static/MqWv-Y9HiB2_KCflF20PP/_buildManifest.js",
revision: "da7188f9e1f939567016a2317720dc51"
},{
url: "_next/static/MqWv-Y9HiB2_KCflF20PP/pages/_app.js",
revision: "f8b6d0a28a7d558551eb6391a89e4a23"
}, {
url: "_next/static/MqWv-Y9HiB2_KCflF20PP/pages/_error.js",
revision: "f37e0a171bb16b16040c90df34522d96"
}, {
url: "_next/static/chunks/framework.b347b462804689eaf927.js",
revision: "6deca90db3f45a916770bb0e41b13c47"
}, {
url: "_next/static/runtime/main-e7b4cabd257a4cc3b967.js",
revision: "890b84d502df85433e36acdf3cf74224"
}, {
url: "_next/static/runtime/polyfills-f916fbf10dc4121ae9cd.js",
revision: "d9323c6914d005baba12d60770880583"
}, {
url: "_next/static/runtime/webpack-e103235a3ab9d95a6af4.js",
revision: "8bcbba6f506d61d82d4064c4b346a8aa"
},
// BASE FILES END
// PAGE FILES START
{
url: "_next/static/MqWv-Y9HiB2_KCflF20PP/pages/index.js",
revision: "6ba52db6a6bb884b8fafebfa4cf546e8"
}, {
url: "_next/static/MqWv-Y9HiB2_KCflF20PP/pages/latest-news.js",
revision: "25cd2877186c0b93bef4deeeb8b3cb7c"
}, {
url: "_next/static/MqWv-Y9HiB2_KCflF20PP/pages/next-events.js",
revision: "2ef7b0df9ce3fccdd3bae4e86f5173b9"
}, {
url: "_next/static/MqWv-Y9HiB2_KCflF20PP/pages/profile.js",
revision: "89527553568411baf5e7c6b805f00e62"
}, {
url: "_next/static/MqWv-Y9HiB2_KCflF20PP/pages/signin.js",
revision: "01883f6cc3a11498246bcc7882c70c4c"
},
...
// PAGE FILES END
// CHUNK FILES START
{
url: "_next/static/chunks/596ac167622d5d88a275aa870b98bfe10a2d1a1c.aada1b70c5e59113cfa0.js",
revision: "1f845cd5bf11ae86bd19e00f50a94785"
}, {
url: "_next/static/chunks/8ab5f57d4e90de3a37b5e6b66aec8a1d67553e8e.829705e26d6c76bf7ca5.js",
revision: "15a269bcc53e9ea86fa833192b2b5aa0"
}, {
url: "_next/static/chunks/c2fc468355bab5579cbc197ee84c663065a62816.17832137b27cd0ba4068.js",
revision: "117596cdf7a332d8c46cec972085667f"
},
...
// CHUNK FILES END
]
So, in this example if I'm accessing /
which is the page index.js
, is there a way (a cache strategy for example) to only download and cache that page, the chunks needed and the base JS files; and not the whole pages of the web app (in this example: latest-news.js
, next-events.js
, profile.js
, signin.js
...)?
I'm not 100% certain, I'd check the workbox docs.
The same problem. Should be able to disable precache bundles!
Same issue so I use this options to prevent it.
workboxOpts: {
// Do not precache images
exclude: [/\.(?:png|jpg|jpeg|svg)$/],
// Ignore all URL parameters.
ignoreURLParametersMatching: [/.*/],
dontCacheBustURLsMatching: /.*/,
runtimeCaching: [
{
urlPattern: /\.(?:png|jpg|jpeg|svg)/,
handler: 'CacheFirst',
},
{
urlPattern: /^https?.*/,
handler: 'NetworkFirst',
options: {
cacheName: 'offlineCache',
expiration: {
maxEntries: 200
}
}
}
]},