PreEmptive logo

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

R8-Blog-e1606231205905

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 building 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 essentially 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; going straight to dex from Java source code is possible. That two-stage conversion slows down the build, slows down developers, and puts negative pressure on the entire ecosystem.

Google has demonstrated that it takes 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 speed bumps.

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 provided support via its own implementation inside of Jack. But those third-party plugins no longer worked because they had no 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 deprecated 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 significant architectural improvement—one less tool in the toolchain, and it 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 following noticeable architectural change is to skip the bytecode stage entirely.

That’s a massive change for third-party plugins, and Google will have to take it slowly if they want it to be accepted. With D8 and R8, they have demonstrated 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 significant 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 talking with our customers and teams who want better app protection!

In This Article:

Start a Free Trial of PreEmptive Today