docs/speed/binary_size/optimization_advice.md
Read first: binary_size_explainer.md
This document primarily focuses on Android and Chrome OS where image size is especially important.
[TOC]
Feel free to email [email protected].
Grit supports gzip and brotli compression for resources in the .grd files
used to build the resources.pak file.
Note that compress="gzip" is already the default behavior for HTML, JS, CSS
and SVG files, when the compress attribute is not specified.
compress="brotli") as
follows
Changes that will significantly increase the Chrome binary size should be made with care and consideration:
Strings do not compress well individually, but an entire l10n file compresses very well.
There are two mechanisms for compressing Chrome l10n files.
For desktop Chrome, string resource files generate individual .pak
files, e.g. generated_resources_en.pak.
These get combined into locale specific .pak files, e.g.
locales/en-US.pak
On Chrome OS, we set'compress = true in chrome_repack_locales.gni,
which causes these .pak files to be gzip compressed.
(Chrome identifies them as compressed by parsing the file header).
So, Chrome strings on Chrome OS will be compressed by default, nothing else needs to be done!
messages.json files in
{extension dir}/_locales/{locale}.
messages.json.gz) as part of their build step.type="chrome_messages_json_gzip" for each <output>
entry in the .grd file.messages.json.gz in the .grd and strings.gni
files..svg following this guide..png images, see how few unique colors you can use without a
noticeable difference.
drawable-xxxhdpi are omitted (they are not
perceptibly different from xxhdpi in most cases).android-binary-size trybot to see the size of the images as webp,
or just build ChromePublic.apk and use unzip -l to see the size of the
images within the built apk.In most parts of the codebase, you should try to optimize your code for binary size rather than performance. Most code runs "fast enough" and only needs to be performance-optimized if identified as a hot spot. Individual code size affects overall binary size no matter the utility of the code.
What this could mean in practice?
Practical advice:
.data.rel.ro:
.rodata:
.text:
std::vector of bare pointers will very likely be ICF'ed, but one
that uses smart pointers gets type-specific destructor logic inlined into
it.Disassemble() feature of
supersize console to see what is going on.
const char * and const std::string& overloads rather than
a single std::string_view.<clinit>()).
<clinit>(). There is often little
advantage to initializing class fields statically vs. upon first use.onFailure() vs onSuccess(), have an
onFinished(bool).onTextChanged(newValue), onDateChanged(newValue),
..., have a single onChanged(), where callbacks use getters to retrieve
the new values.
equals(), toString(), hashCode() unless necessary. Since
these methods are defined on Object, R8 can basically never remove them.@CheckDiscard to methods or classes that you expect R8 to inline.BuildConfig.ENABLE_ASSERTS to strip it in release builds.enable_proguard_obfuscation = false and use
//third_party/android_sdk/public/build-tools/*/dexdump to see how code was
optimized directly in apk / bundle targets.strip_resources = true.resource_exclusion_regex.