The vast majority of Android projects are based on Grale, because Gradle does bring us a lot of convenience. However, after using Gradle, the biggest complaint is that it builds too slowly. There are two ways to solve the slow problem

  • Improve the hardware configuration and choose better hardware such as CPU and memory and hard disk
  • On the software side, reduce unnecessary time consuming and take full advantage of the performance of existing machines.

The main lessons of this article revolve around how to reduce unnecessary time-consuming operations and how to make the most of machine performance.

Adjust gradle configuration

Start the daemon

Compared to not enabling daemons, enabling daemons has the following benefits

  • There is no need to start the Gradle process (JVM instance) every time, reducing initialization-related work
  • Daemons can cache project structures, files, tasks, etc., and reuse previous compilation results as much as possible to shorten the compilation process

Open the daemon is very simple, Mac, for example, in the home directory. Gradle/gradle. The properties files (if no, may need a new file), add the following code.

org.gradle.daemon=true
Copy the code

Or pass gradle parameters

./gradlew task --daemon

Copy the code

To ensure that gradle configuration takes effect, you are advised to use gradle -stop to stop existing daemons.

./gradlew --stop
Copy the code

Run the Gradle task again and start the daemon. If you notice, you can see logs like this.

Starting a Gradle Daemon (subsequent builds will be faster)
Copy the code

Set heap size

Allocate enough memory for Gradle to speed up compilation as well. Modify the file gradle.properties as follows

org.gradle.jvmargs=-Xmx5120m -XX:MaxPermSize=2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
Copy the code

Since Flipboard has a lot of dependencies and files, combined with 8GB of memory on its own device, Gradle is allocated a maximum of 5G. The results so far look good, you can adjust according to their own situation to get an optimal value.

Open the offline

With Offline enabled, Gradle can be forced to use locally cached dependencies, avoiding network reads and writes, even if these dependencies need to be checked from the network.

./gradlew --offline taskName

Copy the code

In the preceding example, add the -offline parameter.

Note: If a dependency does not exist locally, compilation errors will occur. To solve the problem, you only need to temporarily disable offline dependency, and add offline dependency to the following execution after downloading the dependency to the local computer.

Setting up parallel Builds

Today’s projects tend to use many modules. By default, Gradle processes multiple modules one by one. You can imagine how slow this would be to compile. Gradle’s ability to build in parallel allows us to take advantage of the machine’s performance and reduce the time it takes to compile and build.

Modify the gradle.properties file

org.gradle.parallel=true
Copy the code

Or pass parameters to Gradle

./gradlew task --parallel

Copy the code

When the configuration is complete and gradle Task is executed again, we get information like this, indicating that Parallel is enabled and the thread used by each task.

./gradlew clean --info Parallel execution is an incubating feature. ....... :libs:x:clean (Thread[Task worker Thread 3,5,main]) completed. Took 0.005 secs. :libs:xx:clean (Thread[Daemon worker]) completed Thread 3,5,main]) started. :libs: XXX :clean (Thread[Task worker Thread 2,5,main]) completed. :libs: XXXX :clean (Thread[Task worker Thread 3,5,main]) started. :libs: XXXXX :clean (Thread[Task worker Thread 2,5,main]) Completed. Took 0.004 secs. :libs:json-gson:clean (Thread[Task]) completed worker,5,main]) started.Copy the code

Multi-modules engineering optimization

A Project now tends to have a lot of modules, which makes compiling slow. Using — configure-on-demand configures only the relevant modules, not the left and right modules, when executing a task. Especially for multi-module projects, there will be considerable improvement in use.

./gradlew assembleChinaFastDebug --configure-on-demand

Copy the code

Try to stop an existing daemon

When we have daemons running for a while, we find that the compilation is slow, so we can try to terminate the existing daemons and make sure that we start the new daemons for subsequent tasks. Stop existing Gradle Daemons as follows.

./gradlew --stop
Stopping Daemon(s)
1 Daemon stopped
Copy the code

Debug Build disables proGuard

In addition to code obfuscation, Proguard can also be used for code compression, optimization, and pre-validation. This code optimization may take more time. For example, a configuration with code optimization turned on looks like this

-optimizationpasses 5
Copy the code

This means that the code is optimized five times, with the output of the last optimization as input to the next optimization. Over and over again, knowing how many times the configuration was done.

On Android, you can disable Proguard by configuring debug.

buildTypes {
    debug {
        minifyEnabled false
    }

    release {
        minifyEnabled true
    }
}
Copy the code

On Flipboard, for example, when switching from OptimizationPasses =5 to Debug to disable ProGuard, the compile time was reduced by nearly 3 + minutes.

Perform profile analysis

If all of the above configuration may not be working, we should use the Profile function to analyze where the card is.

Gradle provides a function to analyze performance, such as profile. It is easy to use. Such as

./gradlew assembleChinaRelease --profile
Copy the code

After the execution is complete, there is a corresponding result file in the build/reports/profile directory under the root directory of the project, such as profile-2017-04-08-23-06-37.html. Open it in the browser and the result looks like this

As you can see from the summary above, the primary Execution time is Task Execution, so we switch to the Task Execution TAB

We can find the above: apps: droidyue: crashlyticsUploadDeobsChinaRelease incredibly took 4 m26. 26 s, so that is what a task?

In fact, it is the operation of uploading obtrusiveness mapping files of crashlytics, a well-known bug-collecting tool. As the Crashlytics server is in a foreign country, this network operation will be very slow.

To resolve this, you can optionally apply the Crashlytics plugin for error-Prone, a section of Google’s Java and Android Bug analysis tool for enabling Error-Prone.

Through the profile, we can clearly identify the root causes of time consumption and begin to address them in a targeted manner.

The last word

If we optimize without upgrading the hardware, when all of our configurations are applied and the compile time still feels like a long time, then we should also think from a hardware perspective.

There are generally three main influences on the hardware for improving compilation speed

  • CPU: i5 is recommended
  • Memory: The recommended memory is not less than 8 GB
  • Hard disk: SSD is recommended

A mature product with all three would be MBP, such as this Apple MacBook Pro 15.4-inch laptop (Core I7 processor /16GB RAM /256GB SSD flash /Retina display).

When we optimize both hardware and software, our development efficiency will be greatly improved.

Note: Personally, using the above method, the daily debug build time is reduced from about 1 minute to about 30 seconds. My machine is 15.4mBP, I7,8G,SSD.