WKWebViewのキャッシュ
について調べた
potatotips #44
自己紹介
● Twitter
○ hotpepsi
● 趣味
○ 競技プログラミング、ピアノ、テニス、ボルダリング
● ライフワーク
○ デバッグ
● 勤務先
Agenda
● 調査のきっかけ、方法、結果
● OSバージョン毎の比較
● まとめ
調査のきっかけ
● iOS 10で、一部のユーザーのアプリの使用容量が数GBに
● WKWebViewのキャッシュが原因
調査対象
● WKWebViewが保持するデータ
○ コンテンツ(blobs)
■ HTMLや画像、動画データ
○ コンテンツ以外のデータ
■ cookies、local storageなど
● 今回はコンテンツ(blobs)の肥大化が調査対象
調査方法
● 実機
● シミュレータ
● ソースコード
実機とシミュレータでの調査方法
● アプリを用意する
○ 既存のアプリを改造し、数秒ごとにランダムでwebページ
を開く
■ 比較のため、WKWebViewとUIWebViewで試す
○ WKWebViewだけの単純なアプリを作る
● アプリバージョンやOSバージョン毎に内容を比較する
実機のデータ
● アプリのデータをMacに転送する
○ XcodeのDevices and Simulators -> Download Container
○ xcappdataを右クリック -> パッケージの内容を表示
シミュレータのデータ
● ディレクトリの内容を調べる
○ Macでの場所はNSSearchPathForDirectoriesInDomainsな
どを出力させればわかる
○ ~//Library/Developer/CoreSimulator/Devices/
● WKWebViewに関しては、ディレクトリの構成(位置)が実機と
異なるため、今回は参考にならなかった
ソースコード
● https://opensource.apple.com/
○ tar.gzアーカイブをダウンロードしてgrepする
● 該当部分はWebKit2
○ UI process、web process、network processなど、複数の
プロセスからなる、WebKitのAPI層
○ キャッシュを操作するのはnetwork process
OSバージョン毎の比較
● iOS 7 - WKWebViewは存在しない
● iOS 8
● iOS 9
● iOS 10
● iOS 11
iOS 8のWKWebViewのキャッシュ
● コンテンツ(blobs)はNSURLCacheを利用して格納される
○ NSURLCacheを消せば消える
● コンテンツ以外のデータ(cookiesなど)は別のフォルダにある
○ この部分を消すAPIは存在しない
● 最大容量はNSURLCacheに従うため、肥大化しない
iOS 9のWKWebViewのキャッシュ
● WKWebsiteDataStoreが導入された
○ API経由で消すこともできる
● NSURLCacheには書き込まない
○ 最大容量をゼロに設定している模様
● 試した限りでは肥大化しない
iOS 9のWKWebsiteDataStoreのコンテンツ部分
● 定期的に使用容量を確認している
○ Statistics::shrinkIfNeeded()
■ 100000個で消去
○ Storage::shrinkIfNeeded()
■ 最大容量を超えたら消去
● 最大容量の最大値は175MB
iOS 10のWKWebViewのキャッシュ
● APIや実装は、ほぼiOS 9のものと同じ
● しかしiOS 10ではどんどん肥大化していく
● ソースを追ってみたが調べきれず
● 肥大化するのはおそらくバグ
iOS 10のWKWebViewのキャッシュの問題点
● OSの問題
● WKWebsiteDataStoreの問題
iOS 10とキャッシュ
● WKWebsiteDataStoreはアプリに所属し、アプリのキャッシュ
領域に作成される
● キャッシュ領域もアプリの使用容量に含まれる
● キャッシュは、デバイス全体の容量が足りなくなるとOSが削
除するはずだが、ユーザーからはアプリが占有しているように
見える
iOS 10のWKWebsiteDataStoreの問題点
● 自動的に消えず、肥大化する
● APIが貧弱
○ 総容量の制限ができない、総容量がわからない
○ 古いコンテンツ(指定日時以前)だけを消すAPIがない
■ 全部または新しいコンテンツ(指定日時以降)は消せる
余談: iOS 10のUIWebView
● UIWebViewはNSURLCacheを使う
● 10.0、10.1、10.2は容量制限がなく、無尽蔵に増える
● 10.3では修正されている
Bug Reporterで報告
● 以下を報告
○ アプリの使用サイズが肥大化する
● 追記の要望として以下も書いておいた
○ 古いキャッシュを消すAPIがほしい
○ 最大のサイズを指定できるようにしてほしい
WWDCで開発者と話す
● アプリの使用サイズが肥大化することを説明
● 要望を伝えた
○ 古いのを消すAPIを追加できないか?
■ 「blobs以外も一貫性を保とうとすると難しい」
○ キャッシュ領域をアプリ領域から除外できないか?
■ それはもっともなので、検討したい
iOS 11のWKWebViewのキャッシュ
● OSの重要な変更
○ キャッシュがアプリの使用サイズに含まれなくなった
まとめ
● 同じAPIでも、内部実装や挙動が変わることがある
● Appleはちゃんとソースコードを公開している
● iOS 11は良い

WkWebViewのキャッシュについて調べた