PreEmptive logo

R8: A Step in Google’s Android Build Performance Roadmap

Google recently introduced R8, a tool designed to replace ProGuard as the default shrinker in the Android build process. R8 is meant to produce as-good-or-better outputs than ProGuard and to do so faster than ProGuard does, thereby reducing overall build times. It will be enabled by default in the next release of the Android Gradle Plugin (v3.4).

This change removes a long-standing component (ProGuard) and replaces it with entirely new code that does the same thing. Why would Google do such an expensive, risky thing? We’ve been tracking the development of R8 since it first became public, and we have a pretty good idea.

Google is intensely focused on build performance, and R8 is just one step leading toward a single-component toolchain that builds much faster than the current toolchain—possibly by removing traditional Java bytecode from the process altogether. R8 doesn’t make a big difference – builds “after” will be largely the same as builds “before,” albeit with incremental improvements to artifact size and build speed. The value of this step is that it enables Google to iterate even more on the build process – to make even bigger architectural changes – because they don’t depend on third-party components anymore.

Let’s examine the history of the Android build process to understand this and get an idea of where they’re going next.

Android builds have always been inherently complex because they start with Java source, compile it to Java bytecode, and then convert it to Android dex. That bytecode stage isn’t fundamentally necessary; it’s possible to go straight to dex from Java source code. That two-stage conversion slows down the build, slows down developers, and puts negative pressure on the entire ecosystem.

Google has demonstrated that they take that very seriously.

In 2014, Google announced the “experimental” Jack toolchain designed to replace the two-stage build process with a single stage, straight from Java source to dex bytecode. The idea was that Jack would do the entire build in one toolchain without unnecessary conversions—making it much faster.

Unfortunately, that approach hit some major speedbumps.

First, the original two-stage build process was only part of the story. For many developers, the process was three or more stages:

original

Jack needed to provide similar functionality for developers using those additional stages. In the case of shrinking, Google actually provided support via their own implementation inside of Jack. But those third-party plugins no longer worked because they didn’t have any bytecode to operate on. This was a big issue for anyone who used those plugins—and there were many plugins and many users.

Second, some of Google’s other build features—including a key one, Instant Run—didn’t work with the Jack toolchain. This was ironic because Instant Run had effectively the same goal as Jack: to help developers work faster.

So, Jack wasn’t a clear win for the development community. But even so, Google doubled down on it, announcing that they would only support Java 8 language features for developers using the Jack toolchain. This incentivized developers to migrate to Jack, but the community reaction wasn’t positive. In essence, it backfired.

In March 2017, Google relented by deprecating the Jack toolchain and migrated Java 8 support into the core toolchain.

Why is this history important? First, it shows how dedicated Google is to building performance and how far it will go to get it. Second, it explains how we came to have the build toolchain of 2017:

java8

At that point, in 2017, the builds were architecturally even more complex than they were in 2014.

Google did not give up. Later that same year (2017), Google introduced D8, an optional replacement for the dx dex compiler, explicitly designed to run faster and make smaller output binaries. Then, they moved the desugar stage into d8, simplifying the architecture and making the build process even faster. With d8, the build process looks like this:

d8

In 2018, Google made D8 the default dex compiler.

Now, in 2019, Google has introduced r8, which is a replacement for ProGuard and has all the features of d8, so now the build process looks like this:

r8

This is another big architectural improvement—one less tool in the toolchain, and r8 is both faster and better at shrinking than ProGuard. R8 is better all around.

Google appears to be headed in the same direction as Jack: to a one-stage build process that goes directly from Java source to Dex. Now that they have the entire toolchain under their control, we believe they’ll feel more able to continue to evolve the architecture. The next obvious architectural change is to skip the bytecode stage entirely.

Clearly, that’s a huge change for third-party plugins, and Google will have to take it slowly if they want it to be accepted. They have demonstrated, with D8 and R8, that they are willing to make these changes one at a time, so we think they’ll take a more measured approach to this change—and probably succeed.

In conclusion, we don’t see R8 as “just another tool.” It’s “another important step” in an architectural vision that may eventually result in a pure-dex build process.

With that vision in mind, you might imagine we have big changes coming for DashO (our powerful Java obfuscation and application protection tool that integrates tightly with Android)—and we do! We don’t like to talk “futures,” but our customers who are testing early versions of our new approach are excited about the changes.

If you’d like to learn more, please don’t hesitate to contact us. We love to talk with our customers and teams who want better protection for their apps!

In This Article:

Try a Free Trial of PreEmptive Today!