KitchHike Tech Blog

KitchHike Product, Design and Engineering Teams

React Nativeアプリのサイズを35%減らした話 Android編

f:id:sfujisak:20200229214803p:plain

CTOの Shoken です。キッチハイクアプリはReact Nativeで開発を始めて3年目に入りました。アプリのサイズは開発を続けるうちに大きくなっていってしまいます。この記事では React Native アプリが、どのファイルでサイズが大きくなっているかの分析と、Androidでアプリのダウンロードサイズを減らした方法を紹介します。

サマリ

  • キッチハイクアプリでは JS Bundle は 3.4 MB 、フォントは 48 MB だった。
  • Androidはビルド時の最適化オプションとApp Bundleにすることでサイズが 35% 減った。80.6 MB -> 66.8 MB

JS Bundle のサイズを調べる

まずは React Native の JavaScript レイヤーである JS Bundle のサイズを確認します。 react-native start コマンドで Metro を起動させて、 HTTP GET することにより、 JS Bundle をダウンロードできます。

curl コマンドを使った例はこちらです。

curl "http://localhost:8081/index.bundle?dev=false&minify=true&platform=ios" -o bundle.js

f:id:sfujisak:20200229214831p:plain

ダウンロードした bundle.js のサイズをみると、3.4 MB でした。

f:id:sfujisak:20200229215055p:plain

react-native-bundle-visualizer を使った JS Bundle の構成を確認する

JS Bundle の中でどのファイルがサイズを大きくしているかを調べるために react-native-bundle-visualizer を使って可視化してみます。

リポジトリの README.md に従ってコマンドを実行すると、ブラウザで表示されます。

npm install --save-dev react-native-bundle-visualizer
./node_modules/.bin/react-native-bundle-visualizer

f:id:sfujisak:20200229215135p:plain

結果、キッチハイクアプリでは node_modules が 1.32 MB 、components, styles などが 1.07 MB でした。

Android Studio APK Analyzer でディレクトリ別サイズを調べる

JS Bundle の次はディレクトリ別にサイズを分析します。

Android Studio APK Analyzer ( Android Studioのメニュー -> Build -> Analyzer APK ) を使うと、ディレクトリ別に占めているサイズを確認することができます。キッチハイクアプリでは assets/fonts のサイズ大きいことがわかりました。

f:id:sfujisak:20200229215417p:plain

f:id:sfujisak:20200229215525p:plain

キッチハイクはフォントに Noto Sans CJK JP を使っており、 16MB x 3 で 48MB ありました。キッチハイクアプリの63.8% はフォントが占めていることがわかりました。

Android アプリを最適化してサイズを減らす

ここまで React Native アプリでどの部分がサイズを占めているかの調査をしてきました。ここからは Android アプリを最適化してサイズを減らしていきます。

今回は2つのステップを実施しました。

  1. R8 コンパイラを有効化
  2. App Bundleでビルド

ProGuard の後継である R8 コンパイラを有効化

React Native アプリでの Android サイズ最適化では ProGuard を使った enableProguardInReleaseBuilds を有効化 が出てきますが、 Android Studio 3.4 以降を使っているのなら ProGuard より新しい R8 コンパイラが推奨されています。

R8 はコンパイル時タスクとしてコードの圧縮、リソースの圧縮、難読化、最適化を行います。R8 はこれまでのProGuard ルールファイルと連携するため、R8 を使用するように Gradle プラグインを更新しても、これまでのルールを変更する必要はありません。

R8 を有効化するために android/gradle.propertiesandroid.enableR8=true を追加します。

//android/gradle.properties

android.enableR8=true

コードの圧縮などを有効にするため、 android/app/build.gradle に追加します。今回はついでに resConfigs プロパティも追加しました。これで ja 以外のアプリが必要としない代替リソースファイルを削除します。

//android/app/build.gradle

release {
  minifyEnabled true
  shrinkResources true
}

defaultConfig {
  resConfigs "ja"
}

R8 コンパイラ有効化の結果

R8 コンパイラ有効と resConfigs プロパティを追加することで、リリースビルドがディスクサイズ上で 80.6 MB -> 66.8 MB となりました。

f:id:sfujisak:20200229215630p:plain

Android App Bundle にする

Android の新しい配布形式である App Bundle にすることでサイズ削減を試みます。Google Play Console でAPKをアップロードする時に出てきているこれです。

f:id:sfujisak:20200229215731p:plain

この App Bundle での配布は各デバイスのアーキテクチャごとにAPKを配布することも含んでいます。なので Multiple APKs で複数のAPKをアップロードして配布することが App Bundle を使うことによって必要なくなります。

React Native アプリのサイズ削減で enableSeparateBuildPerCPUArchitecture を有効にした Multiple APKs での配布が紹介されている記事が出てきますが、今後は App Bundle にする方が良いでしょう。

ビルド準備

App Bundle 配布ではアップロードするバイナリは apk ( Android Application Package ) 形式から aab ( Android App Bundle ) 形式に代わります。 aab 形式で配布するために、Google Play Console でアプリ署名鍵を有効にします。

Google Play Console の左サイドバーにある アプリの署名 にいきます。

f:id:sfujisak:20200301125114p:plain

f:id:sfujisak:20200301124354p:plain

今回は Android Studio からエクスポートした鍵をアップロードする 方法で行いました。

鍵のアップロード

Android Studio -> Build -> Generate Signed Bundle / APK... から必要な情報を入力していきます。鍵は最初にアプリを公開した時に使った情報です。

f:id:sfujisak:20200229215810p:plain

アップロード鍵を Google Play Console に登録することで、アプリ署名鍵が有効になりました。

f:id:sfujisak:20200229225346p:plain

bundleRelease コマンドで aab ファイルを作成

apk ファイル作成時には ./gradlew assembleRelease を使っていましたが、 aab ファイルでは ./gradlew bundleRelease を使います。コマンド実施後、 android/app/build/outputs/bundle/release/app.aab が作成されます。

アップロード後、サイズ35%減に成功

今回、 R8 コンパイラを有効化と App Bundle でビルドの2つを実施した結果、Androidアプリのダウンロードサイズが 35% 減らすことに成功しました。

f:id:sfujisak:20200229215854p:plain

まとめ

この記事では React Native アプリがどのファイルでサイズが大きくなっているかの分析と、Androidアプリのダウンロードサイズを減らした方法を紹介しました。設定ファイルの変更とApp Bundle化することで、当初の想定よりも手軽にダンロードサイズを減らすことができました。

また、今回は未検証で紹介できませんでしたが、 昨年末に発表されたJavaScriptエンジン Hermes を使えば Android アプリのダウンロードサイズが減ると、Facebookからのアナウンスにあります。React Nativeのバージョンアップした後に試してみたいと思っています。

We’re Heiring

キッチハイクでは、React Native アプリエンジニアを募集中です!

www.wantedly.com www.wantedly.com

参考リンク