perf(ios): incremental-build optimizations#14443
Open
hansemannn wants to merge 5 commits into
Open
Conversation
Reorder the beforeCopy hook so the previous-build manifest fingerprint (size+mtime) is checked before reading source/dest and computing the SHA hash. Unchanged SDK files now reuse the cached fingerprint and skip two fs reads plus a hash pass per file. Skipped for ejs-rendered appFiles and once the Frameworks bulk copy has already replaced the destination this build.
The Xcode template project.pbxproj only changes when the SDK itself changes, yet createXcodeProject re-parses it on every build. Persist the parsed JSON tree under build/incremental/xcode-project, keyed by a sha1 of the template source. Subsequent builds reuse the cached tree instead of running xcodeParser.parse again.
Resolves the long-standing "FIXME: Do these in parallel" in the app icon validation loop. Per-icon fs.readFileSync + appc.image.pngInfo are now hoisted into a Promise.all that runs concurrently; the order-sensitive validation/categorization (which mutates lookup, appIconSet, flattenIcons, resourcesToCopy) stays sequential over the resolved buffers.
Each image asset was awaiting one writeAssetContentsFile per parent directory level, sequentially, and writing the same namespace marker many times (once per image in that directory). Collect unique namespace directories in a Set, then write both the namespace markers and the imageset manifests via a single Promise.all at the end.
processLaunchLogos was serially stat+read+hashing the LaunchLogo.png source and then calling fs.existsSync per missing destination inside a forEach. Hoist all of that into a single Promise.all up front; the synchronous categorization loop then runs over the resolved results. Apply the same pattern to writeAppIconSet, which had fs.existsSync + fs.readFileSync + pngInfo per missing icon inside a forEach.
Collaborator
Author
|
@cb1kenobi WDYT? |
Contributor
|
Did I understand it correctly that it should cache the icons and not regenerate them on each build? If so: at least the log still says it will regenerate all icons, even though I didn't change anything. |
Member
|
@hansemannn gah, my bad, I'll take a peek this weekend. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Five targeted, low-risk perf changes inside
iphone/cli/commands/_build.js. Each is a separate commit so they can be reverted or cherry-picked independently. Net diff: +141 / −64 in one file. No public API or hook contract changes.Came out of a deep audit of the iOS build pipeline. A1/A2 (the bigger ones —
processJSFiles/gatherResourcesworker-pool and wave merging) are intentionally not in this PR; they need more measurement and touch shared task infrastructure.Changes
copyTitaniumiOSFilesbeforeCopyhook: if previous-build fingerprint (size+mtime) matches and dest still exists, reuse the cached entry and skip the source read, dest read, and hash. Skipped for ejs-renderedappFilesand once Frameworks has bulk-copied this build.createXcodeProject: cache the parsed templateproject.pbxprojunderbuild/incremental/xcode-project/template-parsed.json, keyed by sha1 of the source. The template only changes when the SDK changes, so subsequent builds skipxcodeParser.parse().createAppIconSet: resolves the in-file// FIXME: Do these in parallel. Per-iconfs.readFile+appc.image.pngInfonow run viaPromise.all. Validation/categorization stays serial over the resolved buffers (it mutates shared state).createAssetImageSets: was awaiting onewriteAssetContentsFileper directory level per image (the same namespace marker written many times). Dedupe parent directories in aSet, then write namespace markers + imageset manifests in onePromise.all.processLaunchLogos: hoistLaunchLogo.pngstat+read+hash and the per-missing-logoexistsSyncprobes into a singlePromise.all. Same pattern applied towriteAppIconSet's missing-iconexistsSync+readFileSync+pngInfoloop.Test plan
npm run test:iphone(simulator) — clean build then incremental build, verify no regressions in resource copying, asset catalog, icon generationLaunchLogo.png— verify the parallelized stat/read still yields correct missingLaunchLogos setcreateAppIconSetstill triggersforceRebuildstays false and xcodebuild is skippedbuild/incremental/xcode-project/after a build — bothtemplate-src.sha1andtemplate-parsed.jsonpresent, second build logs "Reusing cached parsed pbxproj"