Build Analyzer series, article 3.
In article 1, DOTween increased the APK by 0.46 MiB, but Unity's packed-asset report attributed only 192 bytes to the DOTween DLL path.
In article 2, I wrote down the rule that came out of that: APK size,
BuildReport.summary.totalSize, and packed assets are three different numbers.This time I opened the APK itself.
The question was small, but it bothered me:
If BuildReport.packedAssets only showed 192 bytes for DOTween, where did the 0.46 MiB APK increase actually go?
The answer was not in a Unity asset table.
It was inside the APK.
This sounds harder than it is. I did not decompile anything or read native code. An APK is a ZIP file, so I opened the two builds like ZIP archives and compared the size of each file inside. That is the whole technique.
The two builds I compared
I compared the last two steps from the controlled experiment:
| Step | Build | APK bytes | APK MiB |
|---|---|---|---|
| 6 | Font subset, no DOTween | 17,441,073 | 16.6331 |
| 7 | Same build + DOTween runtime reference | 17,928,357 | 17.0978 |
| Delta | 487,284 | 0.4647 |
Both APKs came from the same Unity project and the same fixed Android settings:
- Unity
6000.3.7f1 - Android APK
- IL2CPP
- ARM64 only
- Development Build off
- Managed Stripping Level: Medium
The generated APKs are under Builds/Experiment/ after running the public experiment project. They are not committed to the repository, but the project can regenerate them.
The quick way to compare APK entries
An APK is a ZIP file, so I compared ZIP entries by path.
This is the shape of the script I used:
from zipfile import ZipFile
def entries(path):
with ZipFile(path) as apk:
return {
item.filename: (item.compress_size, item.file_size)
for item in apk.infolist()
}
before = entries("step-06-font-subset.apk")
after = entries("step-07-dotween-runtime.apk")
for name in sorted(set(before) | set(after)):
before_compressed, before_raw = before.get(name, (0, 0))
after_compressed, after_raw = after.get(name, (0, 0))
delta_compressed = after_compressed - before_compressed
delta_raw = after_raw - before_raw
if delta_compressed or delta_raw:
print(delta_compressed, delta_raw, name)
The CSV I kept from this comparison is here:
https://github.com/hellohanostudio/BuildAnalyzer/blob/main/Results/apk-entry-diff-step-06-to-07.csv
Where the 0.46 MiB went
The goal here was not to fully reverse-engineer the cause. I only wanted to see which files inside the APK received the growth.
Almost all of the compressed APK growth was in three files:
| APK entry | Compressed | Uncompressed |
|---|---|---|
libil2cpp.so |
+380,447 bytes | +1,392,400 bytes |
global-metadata.dat |
+64,350 bytes | +188,984 bytes |
libunity.so |
+42,344 bytes | +92,416 bytes |
Full APK paths are in the CSV linked above.
The final APK grew by 487,284 bytes. Those three entries alone account for 487,141 compressed bytes.
That is basically the whole change.
I can explain the libil2cpp.so and metadata growth from the new managed code path. I do not yet know the exact reason libunity.so moved by 42 KB, so I am treating that row as an observed artifact-level delta rather than a conclusion.
The packed-asset row for the DOTween DLL was still real:
9,192,0.000183,"Assets/Plugins/DOTween/DOTween.dll"
It just was not the whole story.
What this changed for me
Before this, I was thinking in two layers:
- Final APK file size
- Unity packed asset data
After this comparison, I need at least three:
- Final artifact size
- Packed asset contribution
- Files inside the artifact
Packed assets explained the texture, audio, and font steps very well.
They did not explain the DOTween step, because DOTween changed generated code and metadata. The growth appeared mostly in libil2cpp.so and global-metadata.dat.
That does not make BuildReport.packedAssets useless. It just tells me what kind of question it can answer.
The important distinction
For an asset-format question, BuildReport.packedAssets is the right lens:
- Did ASTC reduce the texture payload?
- Did Vorbis reduce the audio payload?
- Did a font subset remove font data?
For a code-growth question, the APK itself is the better lens:
- Did a plugin increase
libil2cpp.so? - Did metadata grow?
- Which packaged file actually changed?
That is the lesson I would carry into a real build analyzer: do not collapse these into one number.
Show the artifact delta first. Then explain it with the right layer.
Sources
- Reproducible project: https://github.com/hellohanostudio/BuildAnalyzer
- APK entry diff CSV: https://github.com/hellohanostudio/BuildAnalyzer/blob/main/Results/apk-entry-diff-step-06-to-07.csv
- Step 7 packed-asset report: https://github.com/hellohanostudio/BuildAnalyzer/blob/main/Results/raw/step-07-dotween-runtime-assets.csv
- Previous article: https://dev.to/hano/what-i-learned-reading-unitys-buildreport-after-building-16-apks-4d7g
Top comments (0)