Skip to content

Discussion: size optimization (-Os) for Apple platforms #257

@pblazej

Description

@pblazej

Context

The Apple xcframework is built with -O2 (optimize for speed), while the android_prefixed_stripped target uses optimize_for_size=true (-Os). This is inherited Chromium behavior — the GN default in build/config/compiler/compiler.gni

optimize_for_size = !is_high_end_android && (is_android || is_castos || is_fuchsia)

opts only Android/CastOS/Fuchsia into size optimization ("favoring speed over size for platforms not listed below"), so Apple lands on the -O2 branch of config("optimize"). The build orchestration (webrtc-sdk/webrtc-build: apple/xcframework.shCOMMON_ARGS) doesn't override it.

There's no technical blocker to building Apple with -Osandroid_prefixed_stripped (webrtc-sdk/webrtc-build#50, M144.7559.01) already establishes the pattern. Opening this to discuss aligning Apple with that approach.

Measured impact

LiveKit-prefixed WebRTC, iOS arm64 device slice, M144 (aea24a1…), Release, stripped:

Build Uncompressed Δ install gzip (≈ download) Δ download
-O2 (current) 11.29 MB 5.24 MB
-Os (optimize_for_size=true) 9.95 MB −1.34 MB (−11.9%) 4.62 MB −0.62 MB (−11.8%)
-Oz (reference only — see below) 9.39 MB −1.91 MB (−16.9%) 4.26 MB −0.97 MB (−18.6%)
-Oz + ThinLTO (reference only) 9.23 MB −2.06 MB (−18.3%) 4.17 MB −1.07 MB (−20.4%)

-Os is the relevant row — it's the same flag the Android stripped target already ships. The -Oz/ThinLTO rows are an upper bound only; neither is used anywhere in this project today (Android-stripped is -Os; -Oz is Chromium-gated to Fuchsia/cast only).

Notes:

  • Savings are almost entirely __TEXT,__text (code); __DATA is unchanged.
  • The hot media codecs (libvpx/opus/dav1d/aom) compile under :optimize_max regardless of optimize_for_size, so they stay -O2+. These deltas are the non-codec WebRTC code shrinking — the realtime encode/decode paths are unaffected.

Proposed change

Add optimize_for_size=true to the Apple build's GN args (apple/xcframework.sh COMMON_ARGS in webrtc-sdk/webrtc-build) — a one-line, no-patch change that mirrors android_prefixed_stripped. Chromium's config("optimize") already emits -Os for Apple once the flag is set.

Options for how far to go:

  1. -Os on the shipped Apple framework (recommended starting point) — precedented, low-risk (-Os is "size-conscious -O2"), ~1.3 MB install / ~0.6 MB download per arch.
  2. A separate apple_prefixed_stripped variant — mirror the Android stripped target (size + codec trims) as an opt-in artifact, leaving the default on -O2.
  3. Status quo — keep -O2 if Apple realtime headroom is worth more than ~1.3 MB.

-Oz/ThinLTO are intentionally not proposed here: no precedent in the project, -Oz needs a patch to the GN config, and the extra ~5% isn't worth the added perf risk + maintenance unless there's specific appetite. Easy to revisit separately.

Open questions

  • Perf: codecs are protected (optimize_max), but -Os still touches pacing / jitter-buffer / network / signaling code. Has anyone benchmarked -Os WebRTC on Apple for encode/decode latency, CPU, battery?
  • Default vs opt-in: apply to the single shipped framework, or ship a separate _stripped (extra publish + larger release matrix)?
  • Intentionality: is Apple's speed default deliberate, or unconsidered Chromium inheritance?

Happy to share full bloaty breakdowns and repro scripts.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions