react-native icon indicating copy to clipboard operation
react-native copied to clipboard

RN 0.62 upgrade renders huge iOS ipa build

Open dquessenberry opened this issue 4 years ago • 31 comments

Description

I recently upgraded from RN v0.60.5 to RN v0.62.2 and I noticed that my iOS release builds are now producing an .ipa file nearly triple in size, from ~50MB to ~130MB, however the adhoc builds increased from ~25MB to ~29MB. No other changes have been made to my app besides the upgrade, which I followed the Upgrade Helper tool for the migration. I did have one build issue with Flipper, which I was able to solve by modifying my pod file's flipper post install following these instructions. I can't seem to find any reason why my iOS build would be producing such a large release ipa file. I'm guessing it has something to do with Flipper, but that is simply a guess. I do have several existing images and fonts that I can probably be removed from my app to decrease the overall size, but regardless, why would my builds produce such a huge increase in size? I can't seem to find any reason for this. By the way, the Android build produces an release apk size fairly similar to the pre upgrade size (~49MB to ~50MB). Also to note, this is not an Expo project, but a RN Cli project.

Additionally, here is my build script that produces both an adhoc and release build:

#/bin/bash

set -e

# Try to run from the project root
if (test "${PWD%%/scripts}" != "${PWD}"); then cd ..; echo ${PWD}; fi

IOS_APP_ID=com.voyaj.ios
WORKSPACE_NAME=voyaj
IOS_SCHEME=voyaj
IOS_CONFIGURATION=Release

DEVELOPMENT_TEAM=FHKD78FHJD


echo $IOS_APP_ID
echo $WORKSPACE_NAME
echo $IOS_SCHEME
echo $IOS_CONFIGURATION
echo $IOS_EXPORT_OPTIONS_PLIST

echo "======================================"
echo "Running Pod install..."
echo "--------------------------------------"
cd ios && pod install
if [[ $? -ne 0 ]]; then
    echo
    echo "Pod install FAILED!"
    exit 1
fi

echo
echo "======================================"
echo "Archiving the iOS project..."
echo "--------------------------------------"
xcodebuild clean archive -workspace ./${WORKSPACE_NAME}.xcworkspace -scheme $IOS_SCHEME -configuration $IOS_CONFIGURATION -derivedDataPath ./build -archivePath ./build/Products/${WORKSPACE_NAME}.xcarchive 
if [[ $? -ne 0 ]]; then
    echo
    echo "Failed to export Adhoc IPA"
    exit 1
fi

echo
echo "======================================"
echo "Exporting Adhoc IPA..."
echo "--------------------------------------"
xcodebuild -exportArchive -exportOptionsPlist "./ExportOptions/Voyaj-${DEVELOPMENT_TEAM}-AdHoc.plist"  -archivePath "./build/Products/${WORKSPACE_NAME}.xcarchive" -exportPath "./build/Products/IPA/AdHoc" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}"
if [[ $? -ne 0 ]]; then
    echo
    echo "Failed to export Adhoc IPA"
    exit 1
fi


echo
echo "======================================"
echo "Exporting Release IPA..."
echo "--------------------------------------"
xcodebuild -exportArchive -exportOptionsPlist "./ExportOptions/Voyaj-${DEVELOPMENT_TEAM}-AppStore.plist" -archivePath "./build/Products/${WORKSPACE_NAME}.xcarchive" -exportPath "./build/Products/IPA/Release" DEVELOPMENT_TEAM="${DEVELOPMENT_TEAM}"
if [[ $? -ne 0 ]]; then
  echo
  echo "Failed to export Release IPA"
  exit 1
fi

echo "IPA package location: ./ios/build/Products/IPA"

React Native version:

System:
    OS: macOS Mojave 10.14.6
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 45.24 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 13.12.0 - /usr/local/bin/node
    Yarn: 1.22.4 - /usr/local/bin/yarn
    npm: 6.14.4 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.7.5 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 28, 29
      Build Tools: 28.0.3, 29.0.2
      System Images: android-29 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 3.6 AI-192.7142.36.36.6392135
    Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_212 - /usr/bin/javac
    Python: 2.7.16 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.11.0 => 16.11.0
    react-native: 0.62.2 => 0.62.2
  npmGlobalPackages:
    *react-native*: Not Found

Steps To Reproduce

Provide a detailed list of steps that reproduce the issue.

  1. Upgrade existing project from 0.60.x to 0.62.2
  2. Modify Flipper post install block (via these instructions). My pod file's filpper post install block looks like this:
# Post Install processing for Flipper
def flipper_post_install(installer)
  installer.pods_project.targets.each do |target|
    if target.name == 'YogaKit'
      target.build_configurations.each do |config|
        config.build_settings['SWIFT_VERSION'] = '4.1'
      end
    end
  end
  file_name = Dir.glob("*.xcodeproj")[0]
  app_project = Xcodeproj::Project.open(file_name)
  app_project.native_targets.each do |target|
    target.build_configurations.each do |config|
      cflags = config.build_settings['OTHER_CFLAGS'] || '$(inherited) '
      unless cflags.include? '-DFB_SONARKIT_ENABLED=1'
        puts 'Adding -DFB_SONARKIT_ENABLED=1 in OTHER_CFLAGS...'
        cflags << '-DFB_SONARKIT_ENABLED=1'
      end
      config.build_settings['OTHER_CFLAGS'] = cflags
    end
    app_project.save
  end
  installer.pods_project.save
end

Expected Results

I expect the release build ipa file size to be similar to the file size prior to upgrading to RN v0.62.2 from RN v0.60.5

dquessenberry avatar May 13 '20 17:05 dquessenberry

Any solution or hot fix yet? I have tried commenting out all Flipper related pods and the release bundle is still way bigger than it was with 0.60.5

lachtos avatar May 15 '20 09:05 lachtos

Hello, I tried run your command

xcodebuild clean archive -workspace ./${WORKSPACE_NAME}.xcworkspace -scheme $IOS_SCHEME -configuration $IOS_CONFIGURATION -derivedDataPath ./build -archivePath ./build/Products/${WORKSPACE_NAME}.xcarchive

with ${..} changed with my info, but I have still the issue I opened here: https://github.com/facebook/react-native/issues/28848

Do you know if this could share the same issue of yours?

azuxx avatar May 15 '20 16:05 azuxx

@azuxx I don't think my issue is related to yours. Your issue seems to be related to an older version of node that doesn't support the spread operator. Perhaps you have multiple version of node installed? Maybe try removing all versions of node and reinstall via Homebrew. According to this ticket related to your issue, removing all versions of node and installing the latest version helped solve the issue. It also states that if you don't have nvm installed to follow these instructions, however I don't have nvm installed on my machine, only npm, so IDK. From your terminal, run $ node -v, and $ npm -v and see what versions are running on your machine. I am currently running node v13.12.0 and npm v6.14.4.

Also, are you able to build a release build via xCode's archive under the Product menu? BTW, you have to select the "Generic iOS Device" scheme to run the archive feature.

dquessenberry avatar May 15 '20 17:05 dquessenberry

@dquessenberry thank you but I have already followed this suggestion (https://github.com/facebook/react-native/issues/28848#issuecomment-625752453) and yes I am using nvm with the latest node. I don't know what else I could try

azuxx avatar May 15 '20 17:05 azuxx

After inspecting the contents of my release ipa and comparing pre and post v0.62.2 builds, it appears this is related to the inclusion of Swift. If I remember correctly, in order to get v0.62.2 to build, I had to create a bridging header, which may have inadvertently included the Swift framework. Does any know if Swift is required for RN v0.62.2? cc @lachtos

dquessenberry avatar May 18 '20 18:05 dquessenberry

After inspecting the content of my release ipa and comparing pre and post v0.62.2 build, it appears this is related to the inclusion of Swift. If I remember correctly, in order to get v0.62.2 to build, I had to create a bridging header, which may have inadvertently included the Swift framework. Does any know if Swift is required for RN v0.62.2? cc @lachtos

You are right. I removed the bridging header from the project and successfully built it (all flipper related code and pods are commented out) and the build size is now back to normal.

lachtos avatar May 19 '20 09:05 lachtos

@lachtos that's great news! I removed the bridging header and did another build, but the Swift framework is still being included. Did you do anything else beside just removing the bridging header - like did you change any build settings too?

dquessenberry avatar May 19 '20 16:05 dquessenberry

@dquessenberry I haven't changed any build settings (I'm attaching my swift related settings in an image below). I deleted the .swift file and the bridging header, did clean and then built. Screenshot 2020-05-19 at 19 18 48

lachtos avatar May 19 '20 16:05 lachtos

@lachtos I can't seem to locate a .swift file in my project. However, I did set the "Always Embed Swift Standard Libraries" configuration on my Project build settings, as well as my main target and test target, to No. I cleaned the project and ran my build scripts again, and that seemed to do the trick as far as build size. However, I do get a warning during pod install that the debug and release ... target overrides the 'ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES' build setting defined in 'Pods/Target Support Files/Pods-myapp/Pods-myapp.debug.xcconfig'. This can lead to problems with the CocoaPods installation. If I commented out the Flipper install in my podfile, the warning goes away. It seems that Flipper, or a library dependency for it, specifically YogaKit, requires Swift to be embedded in the app. So I guess for now I will comment out the Flipper install code from my pod file (although it does looks like a powerful tool) and add some comments to explain why and how to re-enable it. BTW, according to this Flipper documentation, it does looks like Flipper depends on YogaKit, which is written in Swift...

dquessenberry avatar May 19 '20 18:05 dquessenberry

The .swift file I was talking about was the dummy file I created to trigger Xcode to create the bridging header. I think all this swift related stuff is for flipper, which I never intended to use (and I couldn't get my android builds to work with flipper) so I disabled all of it for the time being. This is also a hefty size increase for something that is not being used in production anyway. Hopefully these modifications we made don't compromise the stability of 0.62.2

lachtos avatar May 19 '20 19:05 lachtos

I have the same issue. The size of the ipa file is way huger then it should be. It's one small project. 截屏2020-07-27 19 00 37

Liqiankun avatar Jul 27 '20 11:07 Liqiankun

Same issue here

areeb-hub avatar Aug 17 '20 05:08 areeb-hub

@areeb-hub #29504

Liqiankun avatar Aug 18 '20 08:08 Liqiankun

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

stale[bot] avatar Dec 25 '20 22:12 stale[bot]

I have the same issue. The size of the ipa file is way huger then it should be. It's one small project. 截屏2020-07-27 19 00 37

can you solve this??

iamir4g avatar Jan 23 '21 10:01 iamir4g

The .swift file I was talking about was the dummy file I created to trigger Xcode to create the bridging header. I think all this swift related stuff is for flipper, which I never intended to use (and I couldn't get my android builds to work with flipper) so I disabled all of it for the time being. This is also a hefty size increase for something that is not being used in production anyway. Hopefully these modifications we made don't compromise the stability of 0.62.2

I have a package named react-native-geolocation-service it's required to add swift file and the bridging header so after deleting the package and related stuff (swift & bridging files) I got this size ( from 172 to 61 MB) 🙂

anastely avatar Feb 18 '21 16:02 anastely

@dquessenberry there is a discussion here https://github.com/facebook/flipper/issues/1275 about not building Flipper in production. The resolution is to wrap the Flipper Pod deps with an env variable.

It is correct that the Swift file was added to allow Flipper support. But this was removed in 0.63.x I believe. https://github.com/facebook/react-native/pull/27922

Could you verify this happens in the latest RN version?

safaiyeh avatar Feb 18 '21 17:02 safaiyeh

:warning: Using Old Version
:information_source: It looks like you are using an older version of React Native. Please upgrade to the latest version, and verify if the issue persists. If it does not, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the current release.

github-actions[bot] avatar Feb 18 '21 17:02 github-actions[bot]

I've had the same issue (RN 0.62.2), app jumped about 100mb in size after upgrading, so after some sweat I resolved it with:

  • removing .swift dummy (empty) file
  • removing generated bridging header file
  • removing everything related with Flipper (from Podfile and AppDelegate.m)
  • setting ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES to NO

Hope this helps someone :)

brascene avatar Apr 08 '21 09:04 brascene

I updated from 63.4 to 64.0 and enabled Flipper and Hermes, on iOS, and the .app size in the xcarchive went from 98mb to 650mb. Made me realize the old app size is also way too big. I haven't added any new node_modules to my project. The only change was the upgrade and the use of Flipper / Hermes. @brascene your changes reduced the size by about 150mb down to 500mb - still way too big.

I don't really see any docs on how to do release builds - it would be great to see resolution of this issue as well as updated docs to reflect the proper release build process. I build from Xcode by running Product -> Archive with a Run scheme set to Release. Does anyone have a good release build process or a link to one?

mutablestudio avatar May 02 '21 13:05 mutablestudio

I believe the massive increase in 0.64 is due to this bug in Hermes: https://github.com/facebook/hermes/issues/499

My build size went up to 432mb, but at least once it gets into the app store it's a reasonable size.

jmeistrich avatar Jul 14 '21 15:07 jmeistrich

1.Need to do bitcode enabled - Yes at Build setting tab in xcode. 2.Need to choose deployment target version above ios 13.1 Then once do clean & build and then archive. your .ipa file size will be reduce.

nadimahamad avatar Jul 27 '21 11:07 nadimahamad

I tried the suggestions of @nadimahamad with iOS target 13.2 resulting in:

  • reduced archive size: from 1.162 MB to 591 MB
  • reduced ipa size: from 922 MB to 466 MB
  • reduced hermes size: from 848 MB to 426 MB

Nevertheless ~500 MB for a framework is a lot in my opinion. But if I can trust TestFlight, the final app size on the device doesn't changed at all, it's still around 30MB.

rafaelmaeuer avatar Jul 29 '21 20:07 rafaelmaeuer

1.Need to do bitcode enabled - Yes at Build setting tab in xcode. 2.Need to choose deployment target version above ios 13.1 Then once do clean & build and then archive. your .ipa file size will be reduce.

How can i make bitcode enabled in the project? Have to run in Jenkins

Just go to build settings in xcode and search for bitcode.

nadimahamad avatar Aug 16 '21 16:08 nadimahamad

1.Need to do bitcode enabled - Yes at Build setting tab in xcode.

2.Need to choose deployment target version above ios 13.1

Then once do clean & build and then archive. your .ipa file size will be reduce.

How can i make bitcode enabled in the project? Have to run in Jenkins

Just go to build settings in xcode and search for bitcode.

Should I disable Hermes in podfile?

realtril avatar Aug 16 '21 16:08 realtril

Hermes enabled on iOS is known to cause bigger release files.

safaiyeh avatar Aug 16 '21 16:08 safaiyeh

Lol. I have managed to reduce the archive size from 1GB to 130MB. Thank you @nadimahamad

realtril avatar Aug 16 '21 20:08 realtril

Your most welcome @rafaelmaeuer 😊 FYI: if you still want to reduce .ipa file size then you can do Hermes disable in pod file.

nadimahamad avatar Aug 17 '21 02:08 nadimahamad

I want to have the improved performance from the hermes engine so thats no option for me... But today I compared archive-sizes again when reverting target back to iOS 11 (using Xcode 13.2.1 and RN 0.66.4) and voila: sizes of archives are almost equal now: 529,3 MB (iOS 13.2 target) <--> 529,6 MB (iOS 11.0 target). EDIT: After updating to RN 0.67.0 archive size is still 529,7 MB

rafaelmaeuer avatar Jan 20 '22 15:01 rafaelmaeuer

I used the npx react-native init Test to generate an empty project 0.70.6 with Hermes with iOS Target 13.2 the size is 569MB OMG!

anhnch avatar Dec 21 '22 05:12 anhnch