Optimize your app size with this one trick (Android Dev Summit '18)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] PHIL ADAMS: Hello, everyone. It's great to be here with you all today. My name is Phil Adams, and I'm a researcher here at Google. PIERRE LECESNE: And I'm Pierre Lecesne, software engineer at Google. PHIL ADAMS: We are here to talk to you today about how we're rethinking app distribution on Google Play. We'll talk about the new app publishing format that we announced at I/O and share some new features that we've been working on, digging deeper into some of the topics that you saw covered during the keynote. To start with, let's talk about app size and the impact that it's having on your app. Why does app size even matter? We shared this chart at Google I/O, and you saw it earlier today. Play Store data does show that when the app gets bigger, install success rate goes down. Many users don't have enough space left on their device, and especially in emerging markets, data can be expensive, and connection speeds slow. I want you to think about your own experience, too. How many of you have seen a warning from Play to uninstall apps? Millions of people see things like this everyday. We've started looking into this area more closely, and we have found that freeing up space is a major driver of uninstalls. PIERRE LECESNE: This is obviously a problem for people with low-storage devices, but it's also a problem for people with high-end devices who fill up their devices with HD content. Take the US and the UK. One in five [INAUDIBLE]---- one in five devices have very low storage and are reaching the limit where they can't install or update. A key request we hear from developers is also for help understanding and reducing uninstalls. We ran a user research study last year to look into why users in the US uninstall apps. The leading reason apps were uninstalled straight away, within a day, was quality. However, the leading reason apps or games were uninstalled after a month was to free up space. Apps and games keep getting bigger. Since 2012, apps and games have grown over five times on average. Newer devices have more storage, but the apps, games, high-res photos, and HD videos keep getting bigger, too. Making your app big puts it at risk to suffer from all these downsides. Bigger app lose acquisitions, and bigger apps also get uninstalled to free up space. I'm sure you already know that, and you've probably just considered it a tradeoff. Do you add new features and support more device configurations, but lose installs and drive more uninstalls? We don't want you to have to worry about these tradeoffs. For a few years, there has been a way to optimize for device configurations. You can use multiple APKs. But it's incredibly inefficient, and it's a painful process. This is what it looks like in the Play Console when you have to upload dozens of APKs for a single release. The number of APKs grows quickly across dimensions-- for example, 64-bit, 32-bit, and all the screen densities, and you have to version every APK for each release. It also doesn't help with some of the dimensions. For example, all the languages are still in all the APK-- in every APK. We can do better. Let us show you the solution that we have built for this and see how the new app model helps make your life easier. PHIL ADAMS: So the new app model is focused on improving the whole user acquisition journey, from discovery through to retention. It helps by making your app smaller, directly improving install and uninstall rates. And in addition to that, it makes your releases more manageable. In that context, for the rest of today's session, we'll talk about three important steps that we want to help you with. First, we want to help you convert more installers and minimize uninstalls by building smaller apps. Then we want to make it possible for you to deliver different features to different audiences on demand, only for those users who need them. And finally, we want to help you keep your users up to date on the latest and greatest versions of your app. Let's start with how to make your app smaller. This is where we began with our major announcement at I/O about the Android App Bundle. The App Bundle is the official Android app publishing format. Apps that have already adopted the bundle are seeing an average size saving of 35%. That's compared to a universal APK, and that's quite a lot. How does adopting a bundle lead to such savings? Here's the big idea. Google Play can assist and take care of delivering just what's needed to each device on your behalf. There's no need to send a bunch of languages and device resources, which are not necessary. We support three slicing dimensions out of the box-- languages, screen densities, and CPU architecture. All of this is made possible by split APKs, a feature we added to the Android platform in Android Lollipop. Split APKs allow multiple APKs to be installed on a device and behave as if they're part of the same app. These split APKs can be installed in different combinations on different devices and can be installed all at once upfront or over time, piece by piece. Given a bundle, Google Play starts by putting everything that is common to all devices in the base APK. This includes the Android manifest and the dex files, for instance. We then generate a different split APK for each screen density. Each split will contain all the drawables that would have been selected by the Android framework on that device with that density. We then also generate different split APKs for each native architecture, and we can generate a separate split for each language supported by your app, putting each language's strings in a different APK. Together, we call these splits configuration splits, or config splits. PIERRE LECESNE: Now, when we go to serve an app to a device, we only need to serve a subset of these splits. So if Phil, for example, has a Samsung Galaxy J5, we will install the base APKs, as well as the xhdpi density split, the arm architecture split, and the English language split. But it can get a bit trickier than that. I speak both French and English, and I have specified both languages in my device settings. So my Pixel 2XL will not only receive the correct density and architecture split, but also the French and the English language splits. And if I then move to Brazil and learn Portuguese, I might add Portuguese as a language on my device. When I do this, the Play Store will attempt to download the Portuguese language split for all the apps on my phone. For devices pre-L which don't support split APKs, Play will generator a matrix of standalone APKs for each combination of API and screen density that your app supports. Each of these APK contains all the files necessary for the device, so my old Galaxy Nexus still running Android KitKat would receive the hdpi API and arm APK. Note that all the languages are included in those APKs. Putting it all together, the picture looks like this. You actually don't need to worry about all the details of how these APKs are generated. All you have to do is upload a single app bundle, and Play generates and selects the right things to serve for each device. To summarize-- the App Bundle contains everything. Play processes the bundle, generates optimized APKs, and then signs each APK to deliver to user devices. Note that because Play is now sending the APKs, this means that you need to upload your signing key to Google Play. This is part of the program called App Signing by Play. In conversations we've had with developers, they've asked a reasonable question. Is this secure? The answer is absolutely. As you can imagine, Google takes this very seriously. We protect your key in the same storage we protect Google's own keys. We have engineers for custom security, and you'll benefit from our ongoing investments. PHIL ADAMS: We've been chatting to developers who are already using the App Bundle about what they like. Recently, we've conducted a workshop with some developers from India who make really popular apps. These developers have millions of active installs, and they're very sophisticated about keeping their app size small because their users are very sensitive to it. So this is a useful group for us to learn from. Riafy found that smaller installs improve their conversion rates. RedBus speaks to their release process being more streamlined and easier to manage. And Swiggy reports that switching was a simple process, and they were testing using the bundle within an hour. And it's not just developers in India, of course. All these developers around the world have switched and are seeing fantastic size savings. Duolingo, for example, saw a 56% size saving compared to a universal APK, and it's really hard to get such big savings from incremental optimizations. Switching to the bundle is the simplest and highest-impact thing that most developers can do to reduce app size. Google apps are also adopting the bundle in production, and they're seeing strong savings as well. Google Maps is saving about 15% in size; YouTube, 24%; Google News, 27%. They also report some streamlining of their release process and have even noticed a lift in update rates. So you can see this isn't experimental. This is ready. There are thousands of apps-- thousands of app bundles in production, and it's time for all developers to start moving towards this new publishing format. PIERRE LECESNE: So when you adopt the App Bundle, you're not only gaining size savings today. You will also be benefiting from automatic optimizations in the future as Play introduces them. Here's a cool example of another optimization we're just introducing. We've added a new Android platform optimisation to the App Bundle called Uncompressed Native Libraries. Here's how it works. On Android L and below, native libraries have to be uncompressed from the APK before the platform can use them, meaning the user ends up with two copies of the library. After Android M, the platform can read the library directly from the APK if it's left uncompressed, thus saving a copy on the device. To do it yourself, you will need to upload two versions of your app and create multi APK for pre and post M. If you're using the App Bundle, you just give us your libraries, and we create the required flavor for pre and post M and serve the right APK to the right user. The size savings we're seeing on average are significant-- around 16% reduction in size on disk and 8% reduction in download size. As I explained, the app is smaller on disk because the platform does not need to make a copy of the library, but the download size is also smaller because our compression algorithms perform much better on data that is not already compressed. Our partner Gameloft saw size savings on disk of 22% and 16% on the download size for their game "My Little Pony" using this optimization in the App Bundle. And these savings are in addition to the size savings they're already seeing from switching to the App Bundle. With this optimization, the download is size is smaller, it's faster to install, and takes up less space on disk. If you're using the App Bundle, you get this new optimization without any extra effort. Now, we still want you to remain in control to when these optimizations should be pushed to your users. For that reason, Play will only apply optimizations on App Bundle that have been built with the version of Gradle that introduces the optimization. For example, the Uncompressed Native Libraries optimization will only be applied to your app if you build it with the latest Gradle 3.3, which is already available for download in beta. PHIL ADAMS: Now, let's take a look at how you can build, test, and publish Android app bundles. You can build app bundles in the 3.2 stable release of Android Studio. The build process is very similar to building an APK for most developers, so it's easy to switch. For those who prefer the command line or wish to integrate with automated build systems, the new Gradle Android plugin provides a new set of tasks to build Android app bundles. As you'll remember, you would use the assemble task on the command line for building APKs, and now with the Android App Bundle, you use the new bundle task. Similar to assemble tasks, bundle tasks also allow you to build specific flavors. The bundle task will generate an Android App Bundle and place it in the Outputs folder with the flavor and build type chosen. The build artifact is simply called bundle.aab. We do want developers to retain control over their splits, and so for, if any reason, you need to disable splitting by a particular dimension, you can do so using the new bundle block as shown here. Android Studio and Gradle are not the only ways that you can build bundles today because the format and bundle tool are open source. Others are already adopting them. For example, we're excited to share that games using Unity can now build Android app bundles, too. Unity added support in the 2018 0.3 beta release, and you can join the beta program now. PIERRE LECESNE: So now let's see how you can adapt your testing with the App Bundle. During the development phase, when you need to iterate quickly, you don't need to go through the App Bundle. You can keep building APKs directly from Studio. Much faster. Before a release, you may want to test the APKs that would be generated from the App Bundle. From Studio, this is as easy as creating a new run configuration and selecting APK from App Bundle in the deploy menu. Studio, under the hood, uses the same tool, Playtest, to generate the APKs, so you'll get high fidelity. When you want to share the APKs generated from the App Bundle, say with your QA team, you can use the bundletool command line. This tool is what Play and Gradle use under the hood to generate APKs. We have open source bundletool to be transparent about how we generate APKs, and you can download the bundletool library on the GitHub repo you see here. Bundletool generates what we call an APK set archive, which will contain all the APKs for all the devices that your app supports. We can share this archive, and still using bundletool, you can install it on a connected device, which will simulate what Play does when serving APKs to that device. As you can imagine, an APK set can become quite big, so if you want to build the APKs only for a given device configuration, you can do so by passing to bundletool a device specification in a JSON format. We can share that archive around, which can then be installed on the devices matching the spec. This is what the command line looks like to build an APK set archive from the App Bundle. In this case, we're instructing bundletool to build APKs only for the connected device. If you don't have a device at hand-- if you're generating the archive from a CI system, for example-- you can pass, instead, a device specification in this JSON format. Finally, if you want a unique, easily sharable APK, you can also choose to build a universal APK. This APK does not use splits, but it can be installed on any device, so it is very convenient for sharing. But the best way to test exactly what your users will get is still to go through the internal test track on the Play Console. This way, you are guaranteed to get, byte for bytes, what your users will get. The internal test track is similar to the alpha and beta tracks that you may already be familiar with, but it differs from these tracks in that there is almost no delay between the upload of the bundle and the update being available on the tester's device. You can see, here, how it looks in the Play Console. You can create a list of emails for up to 100 QA testers. The QA testers can then follow the update link, and they'll receive, automatically, the latest version. We know that, for some of you, these testing options are not ideal. And we see a gap in particular between testing in Android Studio and Play's test tracks. So I just want you to know that we're thinking really hard about how to close this gap. PHIL ADAMS: So now, you've built and test bundles. Let's discuss publishing bundles and also a new view that we've added to the releases section. In the Play Console, we're starting to show an estimate when we think that an app could really benefit from using the App Bundle. We'll take a common reference device and calculate what you could save were you switch to the bundle. Once you choose to switch, you manage your release just like you did with APKs. Simply create a new release and drop the App Bundle in the same location where you currently drop your APKs. Do note, in order to aid your migration, you can keep uploading APKs on your production track while you test the bundle in a test track. And when you do this, Play is not going to reassign the APK. We did this so that you can feel confident trying out the App Bundle with a smaller number of users first without affecting your current production user base. Once you've uploaded it, you review your release, you roll it out, and that's it. I can't stress this enough. As Pierre mentioned, there's no more multi APK to deal with. Play Console has created in the background all the APKs for the devices supportive for you. Now that you've uploaded your App Bundle, and Play has done this heavy lifting, it would be really nice to have an overview of what Play has generated for you. To give you this transparency, we've built a new tool in the Play Console called Bundle Explorer, which lets you navigate your uploaded bundles and the generated artifacts. On the first screen of Bundle Explorer, you'll see how much of a size savings you've gained by publishing a bundle. Of course, this is going to be different device by device, and so we calculate this using a popular device configuration. You can also see below a list of device configurations and the total size of the HP case served to those devices. If you click on View Devices, you can see which devices are in each bucket. Alternatively, you can search for supported device by name to download the set of generated APKs that gets served to that specific device. And this is particularly helpful, for example, when you get a bug report for a particular device. So you can get the exact same APKs that Play has served to it. Of course, we haven't forgotten about everyone who uses our publishing API. Uploading bundles is also available via the API, and automation and CI tools are already adopting the bundle-- for example, Fast Lane. You'll find all the documentation at these URLs. PIERRE LECESNE: To recap, that's the latest on the Android App Bundle and how we're making your apps smaller and releases simpler. The next big change the App Bundle introduces is modularization and dynamic code loading. This is an approved, safe way to load features and functionality dynamically, making your app even smaller at install time. Let me tell you how it works. Dynamic features offer yet another way you can reduce the size of your app. Some big features in your app may be used by only 10% of your users, so to avoid having the 90-other percent pay the price of disk space for a feature they don't use, you can choose to extract it in what we call a dynamic feature. Dynamic features can be installed on demand when user requests them, or you can choose to defer installing them to a later time when the app goes to the background. For pre-L devices, which don't support on-demand features, we can fuse the modules into the main app so they're delivered at install time. All of these use cases are supported in production to date, with millions of users benefiting already. Facebook was actually one of our launch partners, and they are using dynamic features in production across their app portfolio. Let's take a look at their story. PHIL ADAMS: App size is really important to Facebook. They evaluate the app size impacts of each new feature carefully to ensure that the benefit of the feature is worth the size increase. Dynamic features means that they can build new features without increasing the size of apps like Facebook and Facebook Lite at install time. Dynamic features also help Facebook with their high-end device strategy. Facebook is able to deliver advanced features to just supported devices. And they can also remove large features that are not used often to avoid taking up space on that device forever. Facebook has told us that dynamic features work well when they're working on a new feature that is separate from the main app. They can have a separate team of engineers working on it. They can then add it to the app without increasing the base app size at install time. Here are some of the examples of dynamic features that Facebook has added to their apps. These are all features that are in production. For example, card scanning is a feature that only a small percentage of Facebook's users are using, so moving it to a dynamic feature avoids it taking up two megabytes on every user's device for the lifetime of that app. Another example is real-time communication. By moving voice and video chat to a dynamic feature, only users with devices that can support them, and who actually want to use them, need to download it. What might that experience look like for a user? Let's take a simple example. Imagine that you have a recipe app, and you want to keep the initial download size small. You observe that, while all of your users like to browse for recipes, only a small fraction of them like to add recipes, and you notice that this functionality takes up significant size in your app. You can choose, therefore, to break this feature out into its own module and serve it only when needed. We can see what it looks like for the user, or what it might look like for the user, here. The app opens, and then the user goes to add a recipe. The app then requests that the module be installed. It's downloaded and installed with progress visible to the user, and the new feature is ready to be used after just a few seconds. Which parts of your app might make good candidates to be broken out as separate features? We think about it using this Venn diagram. If only a smaller fraction of your users use this feature, it could be a good candidate, especially if that feature takes up significant amounts of space. And finally, consider if users can wait a few seconds before downloading and using that feature. If you're interested in modularizing your app, I invite you to check out the Plaid 2.0 project that some of our dev roles have been working on and the associated articles that they published that describe how modularization was achieved for the app. PIERRE LECESNE: Now that we have covered how dynamic features work, let's see how to create them. To create a dynamic module in Android Studio 3.2, all you need to do is use the new dynamic feature wizard. Click on File, New Module, then choose Dynamic Feature Module. Just type in your module's name, and Android Studio will generate a new dynamic feature for you. Under the hood, this is what Studio does. In the manifest of your new module, a split identifier is added. In this case, we'll call it Add Recipe. This is how the Android platform recognizes that, although this APK has the same package name, it's still a different module. Then a new module tag element is added, which allows to configure distribution aspects of the module. This tag is used by the Play Store to read properties of the modules of your app. Next, you declare that this module is an on-demand module by adding the On Demand attribute, meaning that it will be only delivered to users' devices when you request it instead of at install time. Note that on-demand modules are only supported since Android L, so you have to specify as well what Play should do with this module when it generates the pre-L APKs. You can choose to fuse that module into base APK or exclude it completely. And this is configured using the Fusing tag. Here's an example with our recipe app. In addition to the base module, we have two dynamic features. The Add Recipe module is marked with Fuse Equal True, while the other VR module is marked with Fuse Equal False. And you can see that Play will only include the Add Recipe module in the pre-L APK. Now let's look at the build the Gradle files. In the dynamic module, you can see a new Gradle plugin being used called Come and Read Dynamic Feature. You also have to add the base module as a dependency of this dynamic module to access functionality from the base module. Looking at the build Gradle from the base module, the only change is to declare all dynamic modules. This is to instruct Gradle to make the resources stored in the base module available to them. Now that we've created our on-demand modules, let's write the code to download them. In order to interact with the Play Store to request these on-demand modules, we have to use the split install API, which is part of the Play core library. This is a Java clone library that communicates with the Play Store via IPC. The Play Store IPC then communicate with Play servers. The API is structured using the same task framework that you may be familiar with from Google Play services and Firebase APIs. Installation of splits is coordinated by the Split Install Manager. You construct a request with all the modules that you wish to download, and then invoke Start Install to trigger the Play Store to download and install the splits required for the requested modules. For large modules, you'll need to obtain the user confirmation prior to the download via the Split Install API. You'll need to do this whenever an app requests more than 10 megabytes of on-demand modules to be downloaded. The API allows you to listen for updates throughout the download and install process and display this progress-- to allow to display this progress to users. Here, we show the download progress bar. An alternative option for installing modules that aren't required immediately is to use the deferred installation API. These will be installed at a convenient time for the user, generally when they aren't using the device and are on Wi-Fi and charging. And because of this, we allow you to install larger modules-- up to 100 megabytes-- without requiring user confirmation. The Split Install API also allows you to manage your on-demand modules. You can see which modules are installed. And you can choose to uninstall modules that are no longer required by the app. This will free up precious disk space for your users. So when installing an on-demand module on N+ devices, the app does not need to be restarted. Code is available immediately, and new resources and assets are available once you refresh the context object. However, on Android L and M, installing splits requires the app to fully restart. To avoid this, we include a split compact library, which emulates the installation of splits on L and M until the app goes into the background and we can properly install it. If you are familiar with the multidex support library, you will set up split compact in a very similar way. Let's have a look. You have three options to install split compact. You can use the split compact application as your default application, or if you already have an application, you can simply extend it. And if none of these options suits you, then you can still also choose to override the attach base context in your application and invoke splitcomact.install. Now, let's talk about versioning. When you release an update to your app, Play will automatically update both the base module and any on-demand modules that are already installed. So the version of your modules are always in sync. Partners tell us this is something they really like about this model. PHIL ADAMS: Let's now talk about the final step here-- helping users update to the latest and greatest version of your app. You know that Play offers auto update functionality. And many users do have auto update turned on, but not all of them. And in some markets, it's not uncommon for users to have auto updates turned on, but for the device not to meet the requirements for the auto update to take place. For example, they may not connect to Wi-Fi. I'm happy to share that we're launching a new API that helps you prompt users to update without ever leaving your app. You can call this API to determine, first, if there's an update available. And then if so, you can show a prompt to your users so that they can update the app. In this example, the flow is designed for immediate, critical use cases, such as user privacy or revenue-affecting bugs. It's a full-screen experience, where the user is expected to wait for the update to be applied. It's an easy one for you, the developer, to implement because we take care of restarting the app for you. Some of you have built similar flows for yourselves, but this is a standardized method that you can use with very little effort. Instead of that immediate update, you can also put together a flexible update, which does not have to be applied straight away. The really cool thing about this API is that you can completely customize the update flow so that it feels like part of your app. For example, you may choose to nudge users to update with an inline flow, like Google Chrome is doing in this example. Once the user accepts the update, the download happens in the background, so the user can keep using the app. And once the update is complete, it's up to you and your app to decide how to prompt the user to restart, or you can simply wait until the app goes into the background or is closed by the user. Google Chrome is testing this now, and we're inviting early access partners to start testing this with us as well. Talk to your BD manager if you're interested. Let's take a look at the code that allows that flexible in-app update to work. First, you can request an instance of App Update Manager and then request the app update info. This result is going to contain the update availability status. If an update is available, and the update is allowed, the return to app update info object also contains an intent to start the flow. If the app is allowed to start, then you extract this pending intent, and you start it. This will start the download and installation. You can monitor the state of an update by registering a listener for status updates. When the download is complete, you can choose again to install it directly or defer the installation to a more convenient time, for example using a snack bar. The restart happens when complete update is called. So to recap this new API, ensuring your users get the latest update is important. And you can make that happen by following some of these best practices up here on the screen, and also by integrating with our brand-new in-app updates API. The API is available for any app, and so you can get started with it in parallel to switching to the Android App Bundle. PIERRE LECESNE: And that's it. We've now covered how to make your app smaller and create dynamic features using the Android App Bundle, and how you can ensure that your users stay on the latest version of your app using the new in app updates API. If you want to come and chat about any of this, you can find us at the office hours or the demos on the Google Play stand today and tomorrow. Also, if you want to share about what we've talked today with your team, the medium post at this link is a great place to start. Enjoy the rest of your day. Thank you. [MUSIC PLAYING]
Info
Channel: Android Developers
Views: 14,288
Rating: 4.8852458 out of 5
Keywords: type: Conference Talk (Full production);, pr_pr: Android, purpose: Educate
Id: QdoEcfibG-s
Channel Id: undefined
Length: 33min 34sec (2014 seconds)
Published: Wed Nov 07 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.