Chromium Blog
News and developments from the open source browser project
Partitioning Chrome's Code for Faster Launch Times on Android
2021. november 16., kedd
Mobile devices are generally more resource constrained than laptops or desktops. Optimizing Chrome’s resource usage is critical to give mobile users a faster Chrome experience. As we’ve added features to Chrome on Android, the amount of Java code packaged in the app has continued to grow. In this
The Fast and the Curious
post we show how our team improved the speed and memory usage of Chrome on Android with Isolated Splits. With these improvements, Chrome on Android now
uses 5-7% less memory, and starts and loads pages even faster than before.
The Problem
For Android apps (including Chrome on Android), compiled Java code is stored in
.dex files
. The user's experience in Chrome on Android is particularly sensitive to increases in .dex size due to its
multi-process architecture
. On Android, Chrome will generally have 3+ processes running at all times: the browser process, the GPU process, and one or more renderer processes. The vast majority of Chrome’s Java code is used only in the browser process, but the performance and memory cost of loading the code is paid by all processes.
Bundles and Feature Modules
Ideally, we would load the smallest chunk of Java necessary for a process to run. We can get close to this by using
Android App Bundles
and splitting code into
feature modules
. Feature modules allow splitting code, resources, and assets into distinct
APKs
installed alongside the base APK, either on-demand or during app install.
Now, it seems like we have exactly what we want: a feature module could be created for the browser process code, which could be loaded when needed. However, this is not how Android loads feature modules. By default, all installed feature modules are loaded on startup. For an app with a base module and three feature modules “a”, “b”, and “c”, this gives us an Android
Context
with a
ClassLoader
that looks something like this:
Having a small minimum set of installed modules that are all immediately loaded at startup is beneficial in some situations. For example, if an app has a large feature that is needed only for a subset of users, the app could avoid installing it entirely for users who don't need it. However, for more commonly used features, having to download a feature at runtime can introduce user friction -- for example, additional latency or challenges if mobile data is unavailable. Ideally we'd be able to have all of our standard modules installed ahead of time, but loaded only when they're actually needed.
Isolated Splits to the Rescue
A few days of spelunking in the Android source code led us to the
android:isolatedSplits
attribute. If this is set to “true”, each installed split APK will not be loaded during start-up, and instead must be loaded explicitly. This is exactly what we want to allow our processes to use less resources! The ClassLoader illustrated above now looks like this:
In Chrome’s case, the small amount of code needed in the renderer and GPU processes can be kept in the base module, and the browser code and other expensive features can be split into feature modules to be loaded when needed. Using this method, we were able to reduce the .dex size loaded in child processes by 75% to ~2.5MB, making them start faster and use less memory.
This architecture also enabled optimizations for the browser process. We were able to improve startup time by preloading the majority of the browser process code on a background thread while the Application initializes leading to a 7.6% faster load time. By the time an Activity or other component which needed the browser code was launched, it would already be loaded. By optimizing how features are allocated into feature modules, features can be loaded on-demand which saves the memory and loading cost until the feature is used.
Results
Since
Chrome shipped with isolated splits in M89
we now have several months of data from the field, and are pleased to share significant improvements in memory usage, startup time, page load speed, and stability for all Chrome on Android users running Android Oreo or later:
Median total memory usage improved by 5.2%
Median renderer process memory usage improved by 7.9%
Median GPU process memory usage improved by 7.6%
Median browser process memory usage improved by 1.2%
95th percentile startup time improved by 7.6%
95th percentile page load speed improved by 2.3%
Large improvements in both browser crash rate and renderer hang rate
Posted by Clark Duvall, Chrome Software Engineer
Data source for all statistics:
Real-world data
anonymously aggregated from Chrome clients.
Címkék
$200K
1
10th birthday
4
abusive ads
1
abusive notifications
2
accessibility
3
ad blockers
1
ad blocking
2
advanced capabilities
1
android
2
anti abuse
1
anti-deception
1
background periodic sync
1
badging
1
benchmarks
1
beta
83
better ads standards
1
billing
1
birthday
4
blink
2
browser
2
browser interoperability
1
bundles
1
capabilities
6
capable web
1
cds
1
cds18
2
cds2018
1
chrome
35
chrome 81
1
chrome 83
2
chrome 84
2
chrome ads
1
chrome apps
5
Chrome dev
1
chrome dev summit
1
chrome dev summit 2018
1
chrome dev summit 2019
1
chrome developer
1
Chrome Developer Center
1
chrome developer summit
1
chrome devtools
1
Chrome extension
1
chrome extensions
3
Chrome Frame
1
Chrome lite
1
Chrome on Android
2
chrome on ios
1
Chrome on Mac
1
Chrome OS
1
chrome privacy
4
chrome releases
1
chrome security
10
chrome web store
32
chromedevtools
1
chromeframe
3
chromeos
4
chromeos.dev
1
chromium
9
cloud print
1
coalition
1
coalition for better ads
1
contact picker
1
content indexing
1
cookies
1
core web vitals
2
cumulative layout shift
1
custom tabs
1
csrf
1
css
1
dart
8
dashboard
1
Data Saver
3
Data saver desktop extension
1
day 2
1
deceptive installation
1
declarative net request api
1
design
2
developer dashboard
1
Developer Program Policy
2
developer website
1
devtools
13
digital event
1
discoverability
1
DNS-over-HTTPS
4
DoH
4
emoji
1
emscriptem
1
enterprise
1
extensions
27
Fast badging
1
faster web
1
features
1
feedback
2
field data
1
first input delay
1
Follow
1
fonts
1
form controls
1
frameworks
1
fugu
2
fund
1
funding
1
gdd
1
google earth
1
google event
1
google io 2019
1
google web developer
1
googlechrome
12
harmful ads
1
html5
11
HTTP/3
1
HTTPS
4
iframes
1
images
1
incognito
1
insecure forms
1
intent to explain
1
ios
1
ios Chrome
1
issue tracker
3
jank
1
javascript
5
lab data
1
labelling
1
largest contentful paint
1
launch
1
lazy-loading
1
lighthouse
2
linux
2
Lite Mode
2
Lite pages
1
loading interventions
1
loading optimizations
1
lock icon
1
long-tail
1
mac
1
manifest v3
2
metrics
2
microsoft edge
1
mixed forms
1
mobile
2
na
1
native client
8
native file system
1
New Features
5
notifications
1
octane
1
open web
4
origin trials
2
pagespeed insights
1
pagespeedinsights
1
passwords
1
payment handler
1
payment request
1
payments
2
performance
20
performance tools
1
permission UI
1
permissions
1
play store
1
portals
3
prefetching
1
privacy
2
privacy sandbox
4
private prefetch proxy
1
profile guided optimization
1
progressive web apps
2
Project Strobe
1
protection
1
pwa
1
QUIC
1
quieter permissions
1
releases
3
removals
1
rlz
1
root program
1
safe browsing
2
Secure DNS
2
security
36
site isolation
1
slow loading
1
sms receiver
1
spam policy
1
spdy
2
spectre
1
speed
4
ssl
2
store listing
1
strobe
2
subscription pages
1
suspicious site reporter extension
1
TCP
1
the fast and the curious
23
TLS
1
tools
1
tracing
1
transparency
1
trusted web activities
1
twa
2
user agent string
1
user data policy
1
v8
6
video
2
wasm
1
web
1
web apps
1
web assembly
2
web developers
1
web intents
1
web packaging
1
web payments
1
web platform
1
web request api
1
web vitals
1
web.dev
1
web.dev live
1
webapi
1
webassembly
1
webaudio
3
webgl
7
webkit
5
WebM
1
webmaster
1
webp
5
webrtc
6
websockets
5
webtiming
1
writable-files
1
yerba beuna center for the arts
1
Archive
2024
dec.
aug.
jún.
máj.
ápr.
márc.
febr.
2023
nov.
okt.
szept.
aug.
jún.
máj.
ápr.
febr.
2022
dec.
szept.
aug.
jún.
máj.
ápr.
márc.
febr.
jan.
2021
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2020
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2019
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2018
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2017
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2016
dec.
nov.
okt.
szept.
aug.
jún.
máj.
ápr.
márc.
febr.
jan.
2015
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2014
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2013
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2012
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2011
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2010
dec.
nov.
okt.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2009
dec.
nov.
szept.
aug.
júl.
jún.
máj.
ápr.
márc.
febr.
jan.
2008
dec.
nov.
okt.
szept.
Feed
Follow @ChromiumDev
Give us feedback in our
Product Forums
.