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.sh → COMMON_ARGS) doesn't override it.
There's no technical blocker to building Apple with -Os — android_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:
-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.
- A separate
apple_prefixed_stripped variant — mirror the Android stripped target (size + codec trims) as an opt-in artifact, leaving the default on -O2.
- 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.
Context
The Apple xcframework is built with
-O2(optimize for speed), while theandroid_prefixed_strippedtarget usesoptimize_for_size=true(-Os). This is inherited Chromium behavior — the GN default inbuild/config/compiler/compiler.gniopts only Android/CastOS/Fuchsia into size optimization ("favoring speed over size for platforms not listed below"), so Apple lands on the
-O2branch ofconfig("optimize"). The build orchestration (webrtc-sdk/webrtc-build:apple/xcframework.sh→COMMON_ARGS) doesn't override it.There's no technical blocker to building Apple with
-Os—android_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:-O2(current)-Os(optimize_for_size=true)-Oz(reference only — see below)-Oz+ ThinLTO (reference only)-Osis 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;-Ozis Chromium-gated to Fuchsia/cast only).Notes:
__TEXT,__text(code);__DATAis unchanged.:optimize_maxregardless ofoptimize_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=trueto the Apple build's GN args (apple/xcframework.shCOMMON_ARGSinwebrtc-sdk/webrtc-build) — a one-line, no-patch change that mirrorsandroid_prefixed_stripped. Chromium'sconfig("optimize")already emits-Osfor Apple once the flag is set.Options for how far to go:
-Oson the shipped Apple framework (recommended starting point) — precedented, low-risk (-Osis "size-conscious-O2"), ~1.3 MB install / ~0.6 MB download per arch.apple_prefixed_strippedvariant — mirror the Android stripped target (size + codec trims) as an opt-in artifact, leaving the default on-O2.-O2if Apple realtime headroom is worth more than ~1.3 MB.-Oz/ThinLTO are intentionally not proposed here: no precedent in the project,-Ozneeds 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
optimize_max), but-Osstill touches pacing / jitter-buffer / network / signaling code. Has anyone benchmarked-OsWebRTC on Apple for encode/decode latency, CPU, battery?_stripped(extra publish + larger release matrix)?Happy to share full bloaty breakdowns and repro scripts.