iOS×WKWebView環境でのFirestore表示遅延を解決する:原因分析と3つの改善アプローチ
iOSアプリ(WKWebView)上でFirestore Web SDKを利用する際、特定の条件下で画面表示が数分間フリーズする事象が発生しました。本記事では、その技術的な原因分析と、パッケージアップデートだけでは解決しきれない構造的な課題、および具体的な対応策について解説します。この記事を読むことで、WebView環境におけるFirestoreの通信特性と、堅牢なフロントエンド実装のポイントを理解できます。
1. 発生している問題の分析
現在、iOSアプリ内の flutter_inappwebview(WKWebViewベース)において、顧客一覧の表示が3〜4分程度遅延(フリーズ)する現象が確認されています。調査の結果、主な原因は以下の3点に集約されました。
原因①:WKWebViewとFirestore通信の相性
Firestore Web SDKでは、通信経路としてWebChannel(long-polling)を利用します。WKWebView環境では、この通信経路の再利用や復旧が間欠的に停止する特性があり、特に「初回は表示されるが、再進入時に遅延する」という挙動はこのトランスポート層の不備と一致します。
- 現状の設定:
FirebaseModel.ts(line 41) でexperimentalAutoDetectLongPolling: trueを設定。
原因②:タイムアウト処理の欠如
CustomerList.vue (line 195) では、データの取得を以下のように待機していますが、ここにはタイムアウト処理が存在しません。
// 現状のコード:いずれかが停滞すると無限に待機してしまう
const [configResult, res] = await Promise.all([
configModel.get(),
customer.select(),
]);
プロジェクト内の他の画面(SheetList.vueなど)では withTimeout が実装されていますが、顧客一覧画面は特に通信遅延に対して脆弱な構造になっています。
原因③:Configリクエストとの密結合
顧客一覧の描画に直接関係のない GCConfig/storage ドキュメントの照会が、一覧表示の必須条件(Promise.all)に含まれています。そのため、Configリクエストが1つ遅れるだけで、顧客一覧全体が巻き添えで表示されなくなっています。
2. 解決に向けたアプローチ
パッケージアップデートによる改善
現在、firebase@11.10.0 へのアップデートにより、内部の webchannel-wrapper 等が更新されています。これによりiOS特有の通信不具合が緩和される可能性がありますが、「リクエストを無限待機する」というソースコード側の構造を変えない限り、再発のリスクは残ります。
推奨される追加対応策
アップデート後も問題が継続する場合、以下のステップで防御ロジックを組み込むことを推奨します。
| 対策内容 | 目的 |
|---|---|
| タイムアウトの追加 | 通信が停滞した際に処理を切り離し、無限待機を防ぐ |
| リクエストの非同期分離 | Configの取得を待たずに、顧客一覧を先行して描画する |
| ローカルキャッシュの活用 | localStorage 等に前回データを保存し、再進入時に即時表示(プレースホルダー)する |
| 通信手段の切り替え | 解決しない場合、Firestore LiteやREST API、Callable Functionsへの迂回を検討する |
3. まとめ:フロントエンドに求められる「防御的設計」
今回の問題の本質は、iOS WKWebViewの通信特性と、アプリケーション側の「無限待機構造」がバッティングしたことにあります。外部SDKのアップデートに依存するだけでなく、アプリケーション層でタイムアウトやキャッシュ制御を適切に行うことが、ユーザー体験を損なわないための鍵となります。
まずはパッケージの更新を試しつつ、並行して CustomerList.vue のリクエスト構造の見直しを進めるのが最善の策と言えるでしょう。

