2

I started testing size impact of using react-native in existing android project. When created a simple android project(template project with navigation drawer) and created .apk file, it's size was 1.1 MB in release mode.

Then I tried to integrate react-native with it by following steps in doc, https://facebook.github.io/react-native/docs/integration-with-existing-apps.html

after completed this integration and updated my progaurd-rules.pro file with progaurd steps defined on here, https://github.com/luggit/react-native-config/blob/master/Example/android/app/proguard-rules.pro

Proguard-rules.pro file contents are similar to,

# React Native

# Keep our interfaces so they can be used by other ProGuard rules.
# See http://sourceforge.net/p/proguard/bugs/466/
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip

# Do not strip any method/class that is annotated with @DoNotStrip
-keep @com.facebook.proguard.annotations.DoNotStrip class *
-keep @com.facebook.common.internal.DoNotStrip class *
-keepclassmembers class * {
    @com.facebook.proguard.annotations.DoNotStrip *;
    @com.facebook.common.internal.DoNotStrip *;
}

-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
  void set*(***);
  *** get*();
}

-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
-keep class * extends com.facebook.react.bridge.NativeModule { *; }
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
-keepclassmembers class *  { @com.facebook.react.uimanager.UIProp <fields>; }
-keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
-keepclassmembers class *  { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }

-dontwarn com.facebook.react.**

# okhttp

-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**

# okio

-keep class sun.misc.Unsafe { *; }
-dontwarn java.nio.file.*
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn okio.**

Now, size of my release .apk file has jumped to 7.9 MB. This is too much. I can see various e-commerce apps on play store with total size of 9-12 MB. My Hybrid react-native app is the most basic app, Which has just two activities which are doing almost nothing.

To verify my findings, I created a new react-native app by following this doc, https://facebook.github.io/react-native/docs/getting-started.html

When I generated release .apk file for this pure react-native project, again the basic Awesome App .apk size was 6.8 MB.

This is unacceptable. React native is adding too much size to apk. Is there any further improvement possible in my progaurd file? Anything else can be done to improve this?

It will be really helpful, If anyone can share size impact on his/her app due to React native.

ggsrivas
  • 583
  • 7
  • 19
  • Related: https://facebook.github.io/react-native/docs/signed-apk-android.html#enabling-proguard-to-reduce-the-size-of-the-apk-optional – Morrison Chang Oct 15 '17 at 22:53
  • I have already gone through this doc. I am using minify: true in my release build – ggsrivas Oct 15 '17 at 23:14
  • 1
    Be aware that if you are comparing a Java Android app with any app build with a third party framework, you should expect the third party framework based app to add additional libraries which generally makes the project bigger. – Morrison Chang Oct 15 '17 at 23:40
  • Try `-repackageclasses com.yourpackage` and `-allowaccessmodification`. – user1643723 Oct 16 '17 at 01:39
  • @MorrisonChang I agree. But, 6.5 MB is too much. I was expecting progaurd to do a better job and keep the only relevant code. I hope that others would have faced/solved this problem as react-native is quite famous and widely used. – ggsrivas Oct 16 '17 at 03:25
  • @user1643723 Could you please elaborate? Proguard document says that -allowaccessmodification is not good option for library code. – ggsrivas Oct 16 '17 at 03:35
  • Proguard is only for Java classes not Javascript or any C/C++ binaries. And based on this YouTube video: https://youtu.be/8N4f4h6SThc?t=8m52s it appears that React Native bundles its own JavaScript VM for Android in addition to other Java class files. – Morrison Chang Oct 16 '17 at 03:41
  • @ggsrivas "Proguard document says that -allowaccessmodification is not good option for library code" - erm, what? You are not writing a *library*, that depends on React, do you? – user1643723 Oct 16 '17 at 09:31
  • @MorrisonChang I agree with you. But I still hope that there might be a way to optimize this. If not drastic improvement then at least a bit. – ggsrivas Oct 16 '17 at 17:50
  • @user1643723 actually yest, I am writing an SDK which use react to render UI. Anyways, I will try -allowaccessmodification and see if it helps. Thanks – ggsrivas Oct 16 '17 at 17:52
  • As pointed out by @MorrisonChang React Native is bundling it's own Javascript VM in android apk and seems like that is architecture dependent. If I split my apk to arm and X86, apk size is reduced by 50%. This explains why proguard was not very helpful. Thanks for help guys! – ggsrivas Oct 16 '17 at 23:06
  • @ggsrivas Interesting... I don't know what kind of SDK that is (something like Adobe Air, I guess?) but if you need to reduce total size, I recommend you to look into things like UPX-compression of native libraries (upx recently [has gotten support](https://github.com/upx/upx/issues/100) for Android shared libraries). – user1643723 Oct 17 '17 at 13:26
  • Add `splits enable true` and get it down to 4-2MB https://github.com/facebook/react-native/issues/10350 – Ceddy Muhoza Jan 02 '18 at 11:47

1 Answers1

0

The size of apk when created using react-native will always be more than the native-app apk. But you can reduce your apk size when using react-native.

You can see here and here for how to do it.

It is preferred in the documentation itself that

React Native is great when you are starting a new mobile app from scratch. However, it also works well for adding a single view or user flow to existing native applications.

So, I would prefer to create new react-native app instead of integrating with your existing one since you want to achieve the least apk size possible for react-native android app.

Karan
  • 356
  • 2
  • 6