Building one app for two targets from the same checkout leaves both backend trims of every shader bundle in flutter_scene_generated/, and since the app's pubspec packages the whole directory, each target ships the other target's trims too. Found while measuring the bundle-size impact of #353 on examples/smoke_render.
Repro
flutter build macos --debug in examples/smoke_render, then flutter build apk --debug --target-platform android-arm64 in the same checkout.
flutter_scene_generated/ now holds two of everything, e.g. shaderbundle.base.4a5f0586.shaderbundle (966,328 B, the Metal-only trim) and shaderbundle.base.ea6ec455.shaderbundle (1,800,992 B, the Vulkan + GLES trim), likewise material.physical.7ccd704f / material.physical.86d5a369 and material.materials.53f2d724 / material.materials.26b217a3.
- The APK contains both sets. The stale macOS-trimmed base (204,579 deflated) and physical (356,392 deflated) ride along in the Android build for nothing, about 0.75 MB of download; the iOS build from that checkout would carry the Vulkan + GLES trims the same way.
Why
The 0.22.0 fix for "the second and every later flutter run rendering nothing" gave each backend trim its own content hash in the generated file name, which was right, but nothing prunes the previous trim, and manifest.json resolving by source path hides the leftovers from the runtime while flutter.assets still packages the directory.
Proposal
Have the hook remove generated outputs it did not produce in the current build (or at least the other trims of a bundle it just wrote), so the directory holds exactly the current target's set. Alternatively write per-target subdirectories and list only the active one, but pruning is simpler and keeps init's single pubspec entry. A test that builds two trims in sequence and asserts the directory holds one set would cover it.
Anyone who builds iOS and Android from one checkout (most shipping apps) is paying this today, so it is likely the largest shader-related size win available, ahead of any shader variant accounting.
Building one app for two targets from the same checkout leaves both backend trims of every shader bundle in
flutter_scene_generated/, and since the app's pubspec packages the whole directory, each target ships the other target's trims too. Found while measuring the bundle-size impact of #353 onexamples/smoke_render.Repro
flutter build macos --debuginexamples/smoke_render, thenflutter build apk --debug --target-platform android-arm64in the same checkout.flutter_scene_generated/now holds two of everything, e.g.shaderbundle.base.4a5f0586.shaderbundle(966,328 B, the Metal-only trim) andshaderbundle.base.ea6ec455.shaderbundle(1,800,992 B, the Vulkan + GLES trim), likewisematerial.physical.7ccd704f/material.physical.86d5a369andmaterial.materials.53f2d724/material.materials.26b217a3.Why
The 0.22.0 fix for "the second and every later
flutter runrendering nothing" gave each backend trim its own content hash in the generated file name, which was right, but nothing prunes the previous trim, andmanifest.jsonresolving by source path hides the leftovers from the runtime whileflutter.assetsstill packages the directory.Proposal
Have the hook remove generated outputs it did not produce in the current build (or at least the other trims of a bundle it just wrote), so the directory holds exactly the current target's set. Alternatively write per-target subdirectories and list only the active one, but pruning is simpler and keeps
init's single pubspec entry. A test that builds two trims in sequence and asserts the directory holds one set would cover it.Anyone who builds iOS and Android from one checkout (most shipping apps) is paying this today, so it is likely the largest shader-related size win available, ahead of any shader variant accounting.