pwa 更新を帯で知らせる仕組みと、遅い回線で読み込みを1回に直した検証

要点

  • 更新処理が画面側にあるため、古いコードで動き続けるアプリには、後から追加した更新通知の帯も届かない。(出典: 自社の実測(2026-10-19))
  • 動いている版と公開した版を比べ、違う場合に「新しい版が出ています(日時)/更新する」の帯を出す。(出典: 自社の実測(2026-10-18))
  • 遅い回線では、新しい版を取り込む前に読み直していた。修正後は、取り込み中なら切り替わりを待つようにし、読み込み1回で新しい版になった。(出典: 自社の実測(2026-10-19))

ホーム画面から開いても、最新版とは限らなかった

英語学習アプリ Words Admin で調べたのは、以前ホーム画面に追加したPWAが更新されていないという報告だった。社内の利用者からは、「最新版を常に使うには、スマホのChromeでホーム画面に登録しておけばいい?」という疑問も寄せられた。

そこで、Service Workerのファイルの配り方と、画面側に実装した更新処理を確認した。Service Workerのファイルには、毎回取りに行くための設定があった。公開中のService Workerも、待機中の新しい版へすぐ切り替える指示を扱っていた。

確認した記録のうち、配信と切り替えに関する結果は次のとおりだ。

見たもの 結果
Service Workerのファイルの配り方 no-cache, no-store, must-revalidate=毎回取りに行く設定になっていた
公開中のService Worker 待機中の新しい版にすぐ切り替える指示(SKIP_WAITING)を扱っていた
画面側の更新処理 新しい版を見つけたらSKIP_WAITINGを送り、切り替わり(controllerchange)で1回だけ読み直す
更新を確かめるタイミング 1時間おきと、アプリが前面に戻ったとき

ただし、その処理自体が画面側のコードに入っている。古い版のまま固まったホーム画面アプリは、古いコードで動き続ける。新しい版は待機したまま入らず、画面には何も出ないため、利用者本人は気づけない状態だった。

「Chromeでホーム画面に登録すれば常に最新」とは限らない。今回の記録では、iPhoneで本物のホーム画面アプリを作れるのはSafariからで、iOSのChromeから追加すると「Chromeで開くショートカット」になることも確認した。Androidでは、Chromeからの追加で本物のPWAになる。

(出典: 自社の実測(2026-10-18〜10-19))

版を見比べ、利用者が更新を選ぶ帯を足した

2026年10月18日に追加したのは、新しい版の日時と「更新する」という操作を画面に示す帯だ。動いている版と公開した版を比べ、違う場合に「新しい版が出ています(日時)/更新する」の帯を出す。

この仕組みでは、アプリを作るときに、コミットと作った日時を記載した/build-info.jsonを書き出す。このファイルは、Service Workerのファイルと同じくno-storeで配るようにした。

画面は30分おきと、前面に戻ったときにこのファイルを取りに行く。先ほどのService Workerの更新確認は1時間おきだが、帯のために版を見比べる確認は30分おきに行う。利用者が帯の「更新する」を押すと、Service Workerを入れ替えて読み直す流れだ。

ここで決めたのは、新しい版を見つけても勝手には読み直さないことだった。入力の途中で画面を読み直すと、入力が消えるためだ。帯で新しい版を知らせ、読み直すのは利用者が押したときだけにした。

また、ファイルが取れない場合や、版の情報がない場合には、「古い」と表示しない。分からないときには黙る、という動作にした。

単体テストは192件が通過し、追加した5件のうち3件は負のテストだった。本番画面の確認も5/5という記録が残っている。確認した動作には、同じ版では帯が出ないこと、別の版にすると帯と日時が出ること、「更新する」が押せること、ファイルを取得できないときには表示しないことが含まれる。

ただし、更新処理が画面側にあるため、古いコードで動き続けるアプリには、後から追加した更新通知の帯も届かない。この帯を表示するためのコードも、古い版には入っていないためだ。

(出典: 自社の実測(2026-10-18〜10-19))

遅い回線では、読み直す時点が早すぎた

帯を追加した翌日には、通知の判定に使うファイルが、Service Workerのプリキャッシュにも実行時の控えにも入っていないことを確かめた。/build-info.jsonは毎回ネットワークへ取りに行く状態だった。

一方、更新操作には別の問題があった。「更新する」を押してから600ミリ秒で読み直す実装になっていた。遅い回線では、新しい版を取り込む前に読み直していた。修正後は、取り込み中なら切り替わりを待つようにし、読み込み1回で新しい版になった。

検証では、iPhone 13相当のWebKitと本物のService Workerを使い、1ファイルごとに読み込みを1.5秒遅らせた。修正前は、最初の読み直しでは古い版のままで、約5秒後の2回目にようやく新しい版になった。新しい版に切り替わるまでに、読み込みが2回発生していた。

修正では、取り込み中なら切り替わりを示すcontrollerchangeを待つようにした。待つ時間は最長20秒とした。検証条件と結果を並べると、違いは次のようになる。

条件 結果
修正前・1ファイルごとに1.5秒遅延 1回目は古い版。約5秒後の2回目で新しい版になった
修正後・1ファイルごとに1.5秒遅延 取り込み中は切り替わりを待ち、読み込み1回で新しい版になった
修正前・遅延を120ミリ秒に変更 修正前でも読み込み1回で新しい版になった

遅延を120ミリ秒にすると修正前でも1回で切り替わるため、今回の欠陥は遅い回線でだけ出ていた。600ミリ秒後に読み直す動作では、新しい版の取り込みが終わる前に画面を読み直してしまう条件があった。

(出典: 自社の実測(2026-10-19))

古い版で固まっているアプリは、開き直しと追加し直しで対応する

今回の帯には、すでに古い版で固まっているアプリには届かないという限界がある。通知を追加しただけでは、その状態のアプリを直せない。

記録では、まずアプリを完全に終了して開き直し、それでもだめなら削除して追加し直す手順を案内した。iPhoneで追加し直す場合はSafariから行う。動いている版は、画面に表示した開き方・作った日時・コミットの行で見分ける。

帯を追加した後の公開手順にも注意点がある。帯の判定はコミットを比べるため、コミットしないまま公開すると版の印が前と同じになり、帯が出ない。公開前には必ずコミットする。

/build-info.jsonにはコミットと作った日時を書き出すが、帯の判定で見比べているのはコミットだ。日時を表示することと、どの情報で版の違いを判断するかは、実装した内容に沿って確認する必要がある。

版の行が見えない原因は、測り方にあった

画面の確認方法でも、判断を訂正した点があった。「画面の一番下の版の行が見えない」という報告に対して、当初は下段のナビゲーションに隠れていると判断した。しかし、これは測り方の誤りだった。

実際にスクロールしていたのはbodyではなく、内側の入れ物だった。その入れ物をスクロールして測ると、版の行は隠れていなかった。

この記録から得た教訓は、スクロールしている対象がbodyとは限らないことだ。動く入れ物を探してスクロールしてから測り、その座標に本当に対象があるかも確かめる。今回も、内側の入れ物を動かして測ることで、版の行が隠れていないことを確認できた。

業務に置き換えると

社内ツールをPWAで配る際には、今回の記録をもとに、次の点を点検できる。

  • 最初の版から更新を知らせる仕組みを入れる。 更新処理が画面側にあるため、一度古い版で固まると、そのアプリは自分では直らない。版を見比べて知らせる仕組みを、最初の版から入れておく。
  • 版の判定に使うファイルをキャッシュに入れない。 今回はno-storeで配る設定に加え、Service Workerのプリキャッシュと実行時の控えにも入っていないことを確認した。
  • 更新するのは利用者が押したときだけにする。 勝手に読み直すと入力が消えるため、帯で知らせ、「更新する」が押されたときに読み直す。
  • 遅い回線で試す。 今回は1ファイルごとに1.5秒遅らせると欠陥が出たが、120ミリ秒の遅延では修正前でも1回で切り替わった。速い回線では出ない欠陥があった。

(出典: 自社の実測(2026-10-18〜10-19)。回線の遅延条件と読み込み回数の検証は2026-10-19)

この記事は、TechAthletes が自社のサービスを作る中で記録した実測をもとに書いています。業務への導入のご相談は 仕事の窓口 で受け付けています。

✨ Claudeエージェントを複数走らせるならAgent Desk
Terminal tile manager for macOS。全ソース付き $10 買切り。
Agent Desk を見る →

投稿者 TechAthletes 編集部

TechAthletes は、AI・クラウド・開発ツールの技術記事を公開しているメディアです。記事内の商品リンクには広告(アフィリエイトリンク)が含まれます。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です

Click to listen highlighted text!