HN 日本語サマリー

← 一覧へ戻る
Web開発

Service Workerは不要かもしれない

You might not need a service worker (jayfreestone.com)

11 pointsby Fudgel0 コメント

要約

Service Workerのユースケースとして挙げられるSlackの起動高速化やデプロイ時のチャンク維持、Muxのマニフェスト書き換え、Partytownなどの例を挙げ、それらの多くがService Workerなしでも実現可能であることを指摘しています。記事では、真にService Workerが必要なのはオフラインサポート、プッシュ通知、バックグラウンド同期の場合に限られ、それ以外の問題では最善の解決策ではないと論じています。

全文翻訳

Neciuは最近、Service Workerの興味深いユースケースをいくつか分析しました。私はこれに「見抜かれた」と感じました。私の調査で「2019年に試して削除した」2人は、異なる詳細ながらも同じ話をしました。それは、キャッシュ戦略がまずいService Workerが古いアプリをユーザーに提供し、その修正にはキルスイッチワーカーをデプロイし、クライアントがそれを拾うまでに数日間待つ必要があった、というものです。なぜなら、壊れたワーカーが更新チェックのタイミングを制御していたからです。Service Workerがリリースされた当初、私は早期導入者でしたが、同様のシナリオですぐに自滅してしまいました。この記事からいくつかの例を掘り下げてみましょう(まだ読んでいない場合は、まず読んでください!)。 現場でのユースケース Slackの即時起動 記事の中で最も説得力のある例はSlackのものです。つまり、全てのアセットセットをキャッシュし、Reduxの状態を再ハイドレートすることで、単一のネットワークリクエストが解決される前にUIをレンダダリングできるようにする、というものです。ただし、アセットの部分は少し大げさに感じます。彼らは、そのアセットセットのほとんど何も起動間で変化しないことを観察しました。火曜日の朝にSlackを開くユーザーは、月曜日の朝にダウンロードしたのと同じJavaScriptをダウンロードします。HTTPキャッシュでこれを軽減できるはずで、その方がはるかに簡単です。変更されていないアセットの場合、コンテンツハッシュと`Cache-Control: public, max-age=31536000, immutable`により、それらはキャッシュから直接提供されるはずです。それができないのはネットワークフリーな起動です。HTMLと前提となるデータはまだフェッチする必要があります。これは「オフラインサポートが必要か?」という問題に近いと私は主張します。Slackにとっては確かにそうですが、多くのアプリにとってはそうではないでしょう。同じアセットの繰り返しダウンロードを避けたいだけなら、ハッシュ化してネイティブキャッシュを活用すればよいのです。 デプロイ間で古いチャンクを保持する これは興味深い点です。Vercelのような一部のベンダーは「スキュー保護」を持っていますが、ほとんどの人が過去にこれに遭遇したことがあります。クライアント上の古いバンドルが、参照されるアセットがもはや存在しない場合に404を返す、という問題です。デプロイを多くすればするほど、この問題は頻繁に発生します(真のCIを実践している場合、1日に何百回もデプロイしているかもしれません)。Neciuのここでの解決策は、Service Workerを使用してアプリをローカルにキャッシュすることです。しかし、これはバックグラウンドですべてをキャッシュすることを意味します。 ```jsonc { "version": "2026.06.04-1412", // Where does this end? "assets": ["/assets/index-c91d44.js", "/assets/Settings-c91d44.js"] } ``` 私の考えでは、これはルート/コード分割の目的を失わせます。確かに、初期レンダリングは高速化されますが、それはすべての無効化がクライアントにアプリ全体を再フェッチさせることを意味します。私が携わったほとんどのアプリでは、これはほとんど無駄な巨大なペイロードを招くことになります。ユーザーがどのコンポーネント/ページを訪れるかを確実には予測できないため、理論的にはマニフェスト全体のコンテンツをダウンロードする必要があるでしょう。代わりに、静的アセットを(猶予期間の間)保持しておくのはどうでしょうか?完全に削除するのではなく、バケット内に残しておくのです。コンテンツハッシュされたファイル名があれば、デプロイは何も上書きしません。`Settings-a3f8b2.js`と`Settings-c91d44.js`は共存できます。Service Workerはバックグラウンドで無限に実行されるわけではないので、コアの再フェッチロジックはいずれにせよメインアプリに存在する必要があります。ページがポーリングを駆動し、インターバルで、また`visibilitychange`時に`CHECK_VERSION`をポストすることで、バックグラウンドで週末を過ごしたタブはすぐにチェックします。したがって、これもService Workerを必要としません。 Muxのマニフェスト書き換え これは素晴らしいですが、クライアント側にあるべきではないと感じます。記事で言及されているバグは、実際にはロジックがクライアント側にあることの症状です。ビデオプレーヤーはマウントされた瞬間にフェッチを開始し、同じページのワーカーが制御する前であるため、インデックスページにワーカーを登録し、プレーヤーページにリンクする必要がありました。代わりに、書き換えをサーバー側に移動しましょう。そこはより堅牢でテストも簡単です。書き換えが必要なのはマニフェスト(テキストファイル)だけなので、巨大なビデオを追加のインフラ層を通してプルダウンする心配はありません。記事でも指摘されています。 …Cloudflare Workersのようなエッジランタイムは同じフェッチイベントAPIを実装しているため、彼らはステッチングワーカーをCloudflareにそのままデプロイし、動作するURLを取得しました。 Partytown 良い例ですが、Service Workerバージョンは実際にはフォールバックであることに注意する価値があります。Partytownは、ブラウザで利用可能な場合にAtomicsとSharedArrayBufferを使用します。SharedArrayBufferは残念ながらクロスオリジン分離下でのみ機能し、それらのヘッダーはサードパーティの埋め込みを壊す傾向があります。そのため、実際にはService Workerフォールバックが予想以上に使われますが、それでもこれは緊急避難的なものです。 MOCK SERVICE WORKER これは何を構築しているかによりますが、サーバー主導のレンダリング戦略とデータローディングへの移行に伴い、おそらく`setupServer`(Nodeの内部をパッチします)を使用しているでしょう。ライブラリの名前にもかかわらず、リテラルのService Workerに行き着くのは従来のSPAだけでしょう。 では、Service Workerが必要なのでしょうか? Service Workerでできるクールなことはたくさんあります。また、Service Workerでしかできないこともいくつかあります。オフラインサポート、プッシュ通知、バックグラウンド同期には真の代替手段がありません。しかし、それら以外で、Service Workerが真に最善の解決策である問題に私はまだ出会っていません。素晴らしい例がありますか?教えてください。私はそれらを再検討する良い言い訳を探していました。