【Next】PWA対応後videoが裏で読み込み続けられる問題
2022/11/01
Nextでnext-pwaによるPWA化を行った後、裏側でvideo
のsrc
がすべて読み込み続けられる問題が発生しました。
上記画像赤枠のようにvideo
タグのpreload
属性をmetadata
にしていても表示段階からすべての動画が読み込まれるので、対策していないとネットワークリソースが大きく消費される可能性があります。
リファレンスも少なく対応に少し手間どったので、今後同じ問題に直面した方向けに概要を記録しておきます。
原因
最初のリクエスト画像をよくみると左側に歯車アイコンがあるリクエストとそうでないリクエストがあります。
歯車アイコンがないリクエストは通常のリクエストで、video
タグのpreload
属性がmetadata
なので、動画長などのmetadataのみをとってきています。
一方で歯車アイコンがあるリクエストはServiceWorkerからのリクエストを意味しており、video
タグのpreload="metadata"
に関わらず全データを取得しています。
これはNextのPWA化に伴い、ServiceWorkerがファイルをフロントにcacheしようとするために起こる現象です。
すなわち、オフラインでもmp4
などの動画を見れるように、ServiceWorkerが動画のcacheを試みてくれてるわけです。
画像などの軽いファイルではありがたい機能ですが、動画ファイルとなるとGB単位のものあるのでページを開いただけで全データを取得しようとするのは避けたいところです。
また、ServiceWorker自体はページに依存せず裏で動き続けるものなので、ページを切り替えたとしても動画の読み込みは終わらないことも厄介な点です 😱
動画を複数載せている画面とかだと、一気にダウンロードされる可能性もあるので対策しておきましょう(あえて取得させている場合は除く)。
対応
next-pwa
はデフォルトで色々なものをcacheしようとするので、mp4
などをcacheしないようにcache strategyを変更します。
next-pwa
によるPWA対応後のnext.config.js
は例えば以下のようになっていると思われますが、
const withPWA = require('next-pwa')({
dest: 'public',
// runtimeCaching: [...], ← これ
//...
})
module.exports = withPWA({
// next.js config
})
cache strategyの変更はこの中のruntimeCaching
を弄ることで可能です。
runtimeCaching
の詳細に関してですが、next-pwa
自体は内部でworkbox-webpack-pluginを使用しており、runtimeCaching
オプションに関してもこれと同様のものが設定可能です。
next-pwa
がデフォルトで使用しているcache strategyはnext-pwaリポジトリにまとまっています。
mp4
のみをcache strategyから省きたい場合は、上記リンク先のcache strategyをruntimeCaching
へコピペして以下のようにmp4
部分を変更します。
const withPWA = require('next-pwa')({
dest: 'public',
runtimeCaching: [
...
// {
// urlPattern: /\.(?:mp4)$/i,
// handler: 'CacheFirst',
// options: {
// rangeRequests: true,
// cacheName: 'static-video-assets',
// expiration: {
// maxEntries: 32,
// maxAgeSeconds: 24 * 60 * 60 // 24 hours
// }
// }
// },
// ↓ 以下のように変更
{
urlPattern: /\.(?:mp4)$/i,
handler: 'NetworkOnly',
},
...
],
})
module.exports = withPWA({
// next.js config
})
ここではhandler
をNetworkOnly
とすることで拡張子がmp4
のファイルに対してcacheを行わないようにしました。
CacheFirst
やNetworkOnly
などはworkbox
特有のstrategy名であり、詳細はこちらにまとまめられています。
mp4
だけではなく、その他もcacheから外したい場合は適宜handler
を変更してください。
おわり
ここらへんのドキュメント少ない...