perf: reuse Apple runner cache across version bumps#900
Conversation
Size Report
Startup median (7 runs, lower is better):
Top changed chunks:
|
|
e2897b2 to
1799d0d
Compare
This reverts commit 4ee1620.
b821241 to
10ef1ef
Compare
|
Reviewed the latest head, including the new concrete-simulator destination commit. I do not see a blocker. The default iOS/tvOS script path now prefers an available concrete simulator id, but keeps the generic simulator fallback when Residual risk: this is still Apple runner build/cache behavior, so I would treat the PR body’s local Xcode measurements and first-use validation as the device-facing evidence rather than relying on fixture tests alone. With that evidence plus green CI, this is ready for maintainer merge judgment. |
Summary
Reduce Apple runner cold-build and first-use work while keeping the cache reliability boundary intact.
agent-device@0.18.0AGENT_DEVICE_RUNNER_UNIT_TESTSbuild:allactoolruns for tiny branding assets on every cold runner buildAssets.xcassetsand bundled branding images are removed from repo/npm/project inputsgeneric/platform=iOS Simulator, which built arm64 + x86_64 locallybuild:xcuitestcan build one active simulator archFresh measurements on Xcode 26.2, iPhone 17 Pro Max simulator, alternating runs, fresh DerivedData per run:
xcodebuild build-for-testingrunner buildopen settingsthen firstsnapshot -iwith no runner cacheThe build-only number is intentionally modest because Xcode warmup and shared compiler caches dominate after the first run, but the baseline still runs asset catalog work on every clean DerivedData build and the PR branch does not. The first-use CLI comparison is the more representative user path for "runner is not installed yet".
I tested lazy-loading the screen recording Swift surface after these measurements. It saved about 0.54s median on default clean runner builds, but it required a second runner build variant, feature-specific cache keys, session reuse handling for fixed DerivedData paths, and a more surprising first
recordpath. That tradeoff was not worth shipping, so the lazy-recording commit was reverted inb82124170and recording remains part of the normal runner.Latest additional A/B matrix for low-complexity build-setting levers, all run sequentially with fresh DerivedData per build on Xcode 26.2 / iPhone simulator:
ENABLE_TESTABILITY=NOSWIFT_SERIALIZE_DIAGNOSTICS=NO-serialize-diagnosticsSWIFT_EMIT_MODULE_SEPARATELY=NO-experimental-emit-module-separatelySWIFT_ENABLE_INCREMENTAL_COMPILATION=NO-incremental, no reliable wall-time winOne missed lever did pay off for maintainer/CI script builds:
generic/platform=iOS SimulatorRuntime/user runner builds already use concrete simulator destinations, so this does not change the npm
ios-preparepath. It fixesscripts/build-xcuitest-apple.sh/pnpm build:xcuitestby probing CoreSimulator for an available concrete iOS/tvOS simulator with a 3s timeout, and falling back to the generic destination if discovery fails.Earlier profiling experiments that informed the patch:
actoolrun is noisyactoolstill noisyactoolsource input and drops packaged branding assetsI tried running the guarded Swift unit tests via
xcodebuild test-without-buildingon the macOS UI-test target. Even an allowlist of three device-free methods still launched the UI-test host and was slow/problematic locally, so this PR only compiles that surface in a separate CI job. Actually running those cheaply requires a future target split away from the UI-test runner.Validation
pnpm build: rebuilt localdistbefore CLI measurements.pnpm exec vitest run src/platforms/ios/__tests__/runner-client.test.ts src/platforms/ios/__tests__/runner-xctestrun.test.ts src/platforms/ios/__tests__/runner-icon.test.ts: 79 tests passed after reverting lazy recording.pnpm check:quick: lint and typecheck passed after reverting lazy recording.pnpm build:xcuitest: passed for iOS and macOS after reverting lazy recording.node ./node_modules/oxfmt/bin/oxfmt --write ...: completed cleanly earlier; direct invocation used becausepnpm formattried to verify/fetchpnpm@11.1.2without network in this sandbox.npm pack --dry-run --ignore-scripts --json --cache /private/tmp/agent-device-npm-cache: package has 161 files, 568 KB packed / 1.97 MB unpacked, and noAssets.xcassets,logo.jpg, orpowered-by.pngentries.xcodebuild build-for-testingbenchmark: 5 alternating clean DerivedData runs for global 0.18 and PR perf: reuse Apple runner cache across version bumps #900; baseline logs containAssets.xcassets, PR logs do not.31.5s, PR perf: reuse Apple runner cache across version bumps #90021.4swith isolated runner DerivedData/state..tmp/runner-install-comparison-20260627/videos/agent-device-0.18-first-snapshot.mp4.tmp/runner-install-comparison-20260627/videos/agent-device-pr900-first-snapshot.mp4.tmp/runner-install-comparison-20260627/videos/agent-device-runner-first-snapshot-comparison.mp4AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS=1 AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH=/private/tmp/agent-device-swift-unit-compile-derived pnpm build:xcuitest:macos: passed earlier; command line showed-D AGENT_DEVICE_RUNNER_UNIT_TESTS.bb032737a; CI is re-running for this push.