React Native: Optimise build speed

When it comes to optimisation of the time, resources and finances, one of the first things that you may look to optimise is your CI/CD.

I’m not going to promise you some stupid thing, like: “This lifehack will help you optimise your build time over 9000 times” and other full of crap promises. The time that will be saved is individual and depends on multiple factors, like OS, computer resources, libraries versions, caching mechanism, etc.

Let me ask you:

How much time did you spend waiting for your build to complete?

Depending on the service, that you use for CI/CD, how many credits have you spent?

A lot, for both of them.

For example, on some projects that I worked on, it took 1 and a half hours to build React Native iOS release build. This frustrated me because 50$ allowed me to do 4 to 8 builds.

I’m tired of being robbed by platforms that provide machines for CI.

And what if I tell you that more than half of the time you spent waiting for the build was wasted?

So about what we will be talking today?

  • Optimise Flipper
  • Parallelisation

Optimising Flipper

Let’s think for a bit, what can cause slowness in deployment? Usually using tools that will not be used inside the production.

One of those tools is Flipper. Let’s remove it (from the release build, obviously).

So there’re 2 possible configurations you may have in your project if you use Flipper:

  1. If you inited React Native application with version < 70.9. In this case, in your Podfile, you will have use_flipper! line
  2. And if you inited after v70.0. In this case, you will have use_react_native! . It is still possible to use use_flipper! after version 70.0, just don’t be confused.

General steps

Now, we need to create some identifier that will indicate that we’re running a production build. For example, some CI/CD providers have environment variable CI which is a boolean. Or we can create our own. The reason why we cannot use NODE_ENV is that it may be not available or incorrect in XCode or other tools that you may use, like Fastline.

So let’s set the environment variable with the name ENVIRONMENT and set it to true. You can make it in multiple ways:

  • settings variable in your .bashrc / .zshrc
  • set variable in your CI/CD provider
  • set variable environment file
  • call your script with a declared variable like so: CI=true my-script

When we’re done let’s move on to the next stage.

So what goal are we pursuing here? We need somehow detect production build and change a bit how we’re building our application.

Optimising `use_flipper!`

Now let’s head to our Podfile, it usually located under ios folder. In Podfile we want to get our CI variable and tell Cocoapods not to install Flipper.

Like so:

https://medium.com/media/9eda4321a436dfb4e9ae908efcabd7ca/href

Pretty simple, right?

Optimising `use_react_native!`

Open your Podfile under ios folder.

You need to modify it like this:

https://medium.com/media/326b6c41c035d70bb05db9ee08fa2ddf/href

Some explanation

Just a few words about what we did:

  • IS_CI — it’s a Ruby constant
  • ENV.fetch(‘CI’, false) — this is how we get the environment variable, and if it’s present we will fetch the variable, but if we don’t have this kind of variable we are setting this value to false
  • unless — is Ruby equivalent of if not . It’s equal to the expression if !IS_CI
  • we are saying not to use Flipper when we have CI variable as true
  • FlipperConfiguration.disable and FlipperConfiguration.disable — are pre-defined values for flipper_configuration

In case you have any other references to Flipper external modules, you need to apply the same logic as we did for use_flipper! and flipper_post_install .

Check correctness

In purpose to validate that you have done everything correctly, just follow the simple instructions below.

When you’re done with this logic you can run it in ios folder:

bundle exec pod install

or

pod install

One way how you can validate that you’ve done everything correctly is if you had Pods installed locally before — you should see lines like this:

Removing Flipper
Removing Flipper-Boost-iOSX
Removing Flipper-DoubleConversion
Removing Flipper-Fmt
Removing Flipper-Folly
Removing Flipper-Glog
Removing Flipper-PeerTalk
Removing Flipper-RSocket
Removing FlipperKit

Your Flipper plugin set is not necessary and should look like this, so the output may be different.

And here are the results: Project without Flipper was built in 21 seconds and Project with Flipper in 1 minute and 1 second.

Parallelisation

It is worth mentioning that there are xCode preferences that allow us to tweak a bit how xCode compiles your code.

We can tweak the number of threads that xCode uses for building your project, but you need to keep in mind that this will help you to simultaneously build independent targets, so the more you have libraries the more benefit from this method you will receive.

All you need is to adjust xCode preferences (this works for command line builds too, or any other tools that you are using):

defaults write com.apple.dt.xcodebuild IDEBuildOperationMaxNumberOfConcurrentCompileTask n
defaults write com.apple.dt.xcodebuild PBXNumberOfParallelBuildSubtasks n
defaults write com.apple.dt.Xcode PBXNumberOfParallelBuildSubtasks n
defaults write com.apple.dt.Xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks n

Where n is desired number of threads. By default, xCode uses all available cores that your machine has, but some machine CPUs can handle more threads than the physical amount of cores present in your machine with a virtual one.

I usually use the number of cores multiplied by 2 but I’ve also seen multiple times that developers just fetch a number of threads with sysctl -n hw.ncpu command, but, IMHO that makes no sense, but, as always, it’s up to you.

Conclusion

All of these methods can be used with any tool that you’re using for building mobile applications, like Fastline, command line, plain xCode or any other tool that you’re using to build your application.

This is must have set for any project, that will save you time and money.

Hope you had fun today.

As always, your friendly neighbourhood developer.

Follow me for more! Have a blast!

Level Up Coding

Thanks for being a part of our community! Before you go:

🚀👉 Join the Level Up talent collective and find an amazing job


React Native: Optimise build speed was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Andrii Drozdov

When it comes to optimisation of the time, resources and finances, one of the first things that you may look to optimise is your CI/CD.

I’m not going to promise you some stupid thing, like: “This lifehack will help you optimise your build time over 9000 times” and other full of crap promises. The time that will be saved is individual and depends on multiple factors, like OS, computer resources, libraries versions, caching mechanism, etc.

Let me ask you:

How much time did you spend waiting for your build to complete?

Depending on the service, that you use for CI/CD, how many credits have you spent?

A lot, for both of them.

For example, on some projects that I worked on, it took 1 and a half hours to build React Native iOS release build. This frustrated me because 50$ allowed me to do 4 to 8 builds.

I’m tired of being robbed by platforms that provide machines for CI.

And what if I tell you that more than half of the time you spent waiting for the build was wasted?

So about what we will be talking today?

  • Optimise Flipper
  • Parallelisation

Optimising Flipper

Let’s think for a bit, what can cause slowness in deployment? Usually using tools that will not be used inside the production.

One of those tools is Flipper. Let’s remove it (from the release build, obviously).

So there’re 2 possible configurations you may have in your project if you use Flipper:

  1. If you inited React Native application with version < 70.9. In this case, in your Podfile, you will have use_flipper! line
  2. And if you inited after v70.0. In this case, you will have use_react_native! . It is still possible to use use_flipper! after version 70.0, just don’t be confused.

General steps

Now, we need to create some identifier that will indicate that we’re running a production build. For example, some CI/CD providers have environment variable CI which is a boolean. Or we can create our own. The reason why we cannot use NODE_ENV is that it may be not available or incorrect in XCode or other tools that you may use, like Fastline.

So let’s set the environment variable with the name ENVIRONMENT and set it to true. You can make it in multiple ways:

  • settings variable in your .bashrc / .zshrc
  • set variable in your CI/CD provider
  • set variable environment file
  • call your script with a declared variable like so: CI=true my-script

When we’re done let's move on to the next stage.

So what goal are we pursuing here? We need somehow detect production build and change a bit how we’re building our application.

Optimising `use_flipper!`

Now let's head to our Podfile, it usually located under ios folder. In Podfile we want to get our CI variable and tell Cocoapods not to install Flipper.

Like so:

Pretty simple, right?

Optimising `use_react_native!`

Open your Podfile under ios folder.

You need to modify it like this:

Some explanation

Just a few words about what we did:

  • IS_CI — it’s a Ruby constant
  • ENV.fetch('CI', false) — this is how we get the environment variable, and if it’s present we will fetch the variable, but if we don’t have this kind of variable we are setting this value to false
  • unless — is Ruby equivalent of if not . It’s equal to the expression if !IS_CI
  • we are saying not to use Flipper when we have CI variable as true
  • FlipperConfiguration.disable and FlipperConfiguration.disable — are pre-defined values for flipper_configuration

In case you have any other references to Flipper external modules, you need to apply the same logic as we did for use_flipper! and flipper_post_install .

Check correctness

In purpose to validate that you have done everything correctly, just follow the simple instructions below.

When you’re done with this logic you can run it in ios folder:

bundle exec pod install

or

pod install

One way how you can validate that you’ve done everything correctly is if you had Pods installed locally before — you should see lines like this:

Removing Flipper
Removing Flipper-Boost-iOSX
Removing Flipper-DoubleConversion
Removing Flipper-Fmt
Removing Flipper-Folly
Removing Flipper-Glog
Removing Flipper-PeerTalk
Removing Flipper-RSocket
Removing FlipperKit

Your Flipper plugin set is not necessary and should look like this, so the output may be different.

And here are the results: Project without Flipper was built in 21 seconds and Project with Flipper in 1 minute and 1 second.

Parallelisation

It is worth mentioning that there are xCode preferences that allow us to tweak a bit how xCode compiles your code.

We can tweak the number of threads that xCode uses for building your project, but you need to keep in mind that this will help you to simultaneously build independent targets, so the more you have libraries the more benefit from this method you will receive.

All you need is to adjust xCode preferences (this works for command line builds too, or any other tools that you are using):

defaults write com.apple.dt.xcodebuild IDEBuildOperationMaxNumberOfConcurrentCompileTask n
defaults write com.apple.dt.xcodebuild PBXNumberOfParallelBuildSubtasks n
defaults write com.apple.dt.Xcode PBXNumberOfParallelBuildSubtasks n
defaults write com.apple.dt.Xcode IDEBuildOperationMaxNumberOfConcurrentCompileTasks n

Where n is desired number of threads. By default, xCode uses all available cores that your machine has, but some machine CPUs can handle more threads than the physical amount of cores present in your machine with a virtual one.

I usually use the number of cores multiplied by 2 but I’ve also seen multiple times that developers just fetch a number of threads with sysctl -n hw.ncpu command, but, IMHO that makes no sense, but, as always, it’s up to you.

Conclusion

All of these methods can be used with any tool that you’re using for building mobile applications, like Fastline, command line, plain xCode or any other tool that you’re using to build your application.

This is must have set for any project, that will save you time and money.

Hope you had fun today.

As always, your friendly neighbourhood developer.

Follow me for more! Have a blast!

Level Up Coding

Thanks for being a part of our community! Before you go:

🚀👉 Join the Level Up talent collective and find an amazing job


React Native: Optimise build speed was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Andrii Drozdov


Print Share Comment Cite Upload Translate Updates
APA

Andrii Drozdov | Sciencx (2023-01-12T14:26:11+00:00) React Native: Optimise build speed. Retrieved from https://www.scien.cx/2023/01/12/react-native-optimise-build-speed/

MLA
" » React Native: Optimise build speed." Andrii Drozdov | Sciencx - Thursday January 12, 2023, https://www.scien.cx/2023/01/12/react-native-optimise-build-speed/
HARVARD
Andrii Drozdov | Sciencx Thursday January 12, 2023 » React Native: Optimise build speed., viewed ,<https://www.scien.cx/2023/01/12/react-native-optimise-build-speed/>
VANCOUVER
Andrii Drozdov | Sciencx - » React Native: Optimise build speed. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/01/12/react-native-optimise-build-speed/
CHICAGO
" » React Native: Optimise build speed." Andrii Drozdov | Sciencx - Accessed . https://www.scien.cx/2023/01/12/react-native-optimise-build-speed/
IEEE
" » React Native: Optimise build speed." Andrii Drozdov | Sciencx [Online]. Available: https://www.scien.cx/2023/01/12/react-native-optimise-build-speed/. [Accessed: ]
rf:citation
» React Native: Optimise build speed | Andrii Drozdov | Sciencx | https://www.scien.cx/2023/01/12/react-native-optimise-build-speed/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.