アプリの軽量化をする
地震アプリEarthQuakeの開発ログ#3です。
#2はこちら
なんで軽量化するの?
軽量化前では、起動に8秒以上(高スペックPCで)かかっていました。
これはまだ許容範囲だと思う人もいるかもしれませんが、通常のPCでは30秒程かかるようなことも考えられるため、またこれから機能を拡張していくともっと起動に時間がかかっていくと思われるからです。
読み込み時間の短縮の方法についてはすでにいくつか考えついてはいたので、今回それらを実装してみました。
実装前の起動時間
起動時間のうち、私が主に編集が可能なのは初期化処理の時間です。
軽量化をする前の初期化時間は以下の通り(多少の誤差あり)となっています。
WorldLayer: 473ms
LandLayer: 2357ms
BorderLayer: 330ms
CitiesLayer: 2831ms
BorderLayer(Copy): 0ms
Total 5991ms
CitiesLayerはLandLayerを継承したもので、その名の通り地面のポリゴンを生成して表示します。
どちらも処理に時間がかかってしまっているようですね。
合計で6秒かかっています。
また、BorderLayerは枠線を生成して表示しています。
今回はこれらを軽量化していきます。
方法1 起動時の処理を簡略化
まず、これらに時間がかかっている原因の一つに、毎回地物のJsonファイルから計算している点が挙げられます。
どういうことかといいますと、初期化時には以下のような方法で初期化が進んでいるんです。
起動→TopoJsonファイルから地物を読み込み→ジオメトリに変換→
BorderLayer: 地物の重なりから線分がどこに属するか計算→それぞれの線分をSKPathとして保存
LandLayer: 地物からテセレーションを実行→それぞれのポリゴンをSKVerticesとして保存
元のTopoJsonファイルが変わらない限り計算結果はいつでも同じなので、起動時に毎回計算するのは、とても非効率です。
ここで私が目をつけたのがMessagePackという形式です。
これはJson-likeの保存形式を持っていて、さらに読み込み・書き込みがとても速いです。また、lz4での圧縮にも対応していて、ファイルサイズへの懸念も抑えています。
「これなら多少大きいサイズの配列でも保存できそう!」
ということで、計算結果をMessagePackで保存し、それをアプリ内で読み込む方法に変えました。
方法1 結果
WorldLayer: 429ms
LandLayer: 221ms
BorderLayer: 381ms
CitiesLayer: 432ms
BorderLayer (Copy): 0ms
Total 1463ms
なんと合計4.5秒も短縮することができました!
逆にBorderLayerはあまり短縮できていない、というかこれは誤差の範囲です。許してください。
方法2 海外のポリゴンを削除する
(あ、和歌山県の沖合の地震みたいなやつは気にしないでね)
上の画像を見てください。前回の実装によって地理院地図が追加されたものなのですが、海外の緑色のポリゴンが必要ないように見えませんか?
実は内部データ上では別のデータとして扱っているこの世界地図データなのですが、これを削除すればそのデータの読み込み時間が短縮されますよね!
結果的にはWorldLayerの読み込み時間がなくなるので起動が1秒まで縮まります。
見た目ではこうなります。ついでに戻せるように元のコードはコメントアウトしておきました。
結論
軽量化することで、最大で約5秒の短縮が可能となりました。
これからも定期的に軽量化をして、ストレスフリーでより使いやすいアプリにしていきたいと思っております。今後ともよろしくお願い致します。