[browser] WebAssembly SDK targets more incremental#125367
Draft
[browser] WebAssembly SDK targets more incremental#125367
Conversation
Split _GenerateBuildWasmBootJson and GeneratePublishWasmBootJson into smaller targets to enable Inputs/Outputs-based incrementalism for the expensive GenerateWasmBootJson task invocations. Build path split: - _ResolveBuildWasmBootJsonEndpoints: always runs, resolves endpoints - _WriteBuildWasmBootJsonFile: incremental (Inputs/Outputs), writes boot JSON - _GenerateBuildWasmBootJson: always runs, defines boot config as static web asset Publish path split: - _ResolvePublishWasmBootJsonInputs: always runs, resolves publish inputs - GeneratePublishWasmBootJson: incremental (Inputs/Outputs), writes boot JSON When no inputs have changed, the GenerateWasmBootJson task (~100ms) is skipped entirely. The always-running targets handle endpoint resolution and asset definition to ensure downstream item collections remain populated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Split the monolithic _ResolveWasmOutputs target into three targets to enable MSBuild Inputs/Outputs-based skip optimization for DLL-to-webcil conversion: - _ComputeWasmBuildCandidates (always runs): resolves build asset candidates via ComputeWasmBuildAssets, separates DLL candidates into culture/non-culture groups, and computes expected webcil output paths. - _ConvertBuildDllsToWebcil (incremental): runs ConvertDllsToWebcil only when input DLLs are newer than their webcil outputs. The task also retains its internal per-file timestamp checks as a secondary optimization. - _ResolveWasmOutputs (always runs): reconstructs webcil candidate items from build asset candidates using MSBuild item transforms (matching the ConvertDllsToWebcil task's path/metadata logic), then calls DefineStaticWebAssets to produce the final asset definitions. Culture and non-culture DLLs are separated into distinct intermediate items (_WasmWebcilConvertedNonCulture / _WasmWebcilConvertedCulture) to avoid MSBuild batching errors on metadata like RelatedAsset that only culture items define. The _ResolveWasmOutputs target lists _ComputeWasmBuildCandidates explicitly in its DependsOnTargets (before _ConvertBuildDllsToWebcil) to ensure _WasmEnableWebcil is set by _ResolveWasmConfiguration before the conversion target's Condition is evaluated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves MSBuild incrementalism for WebAssembly SDK build targets by splitting monolithic targets into smaller, more focused targets with proper Inputs/Outputs declarations. This allows MSBuild to skip expensive operations (webcil DLL conversion, boot JSON generation) on no-op rebuilds when inputs haven't changed.
Changes:
- The
_ResolveWasmOutputstarget is split into_ComputeWasmBuildCandidates(resolve/classify candidates),_ConvertBuildDllsToWebcil(incremental webcil conversion), and_ResolveWasmOutputs(reconstruct webcil metadata and define static web assets). - The
_GenerateBuildWasmBootJsontarget is split into_ResolveBuildWasmBootJsonEndpoints(resolve endpoints),_WriteBuildWasmBootJsonFile(incremental boot JSON generation), and_GenerateBuildWasmBootJson(define static web asset for boot config). - The
GeneratePublishWasmBootJsontarget is split into_ResolvePublishWasmBootJsonInputs(resolve inputs) andGeneratePublishWasmBootJson(incremental publish boot JSON generation).
...nuget/Microsoft.NET.Sdk.WebAssembly.Pack/build/Microsoft.NET.Sdk.WebAssembly.Browser.targets
Outdated
Show resolved
Hide resolved
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
Improves MSBuild incrementalism for WebAssembly browser build targets in
Microsoft.NET.Sdk.WebAssembly.Browser.targets. On no-op rebuilds where inputs haven't changed, the expensiveConvertDllsToWebcilandGenerateWasmBootJsontasks are now skipped via MSBuild'sInputs/Outputsmechanism.Changes
Boot JSON Generation (commit 1)
Split
_GenerateBuildWasmBootJsoninto 3 targets:_ResolveBuildWasmBootJsonEndpoints(always runs) -- resolves endpoints and fingerprinted assets_WriteBuildWasmBootJsonFile(incremental) -- writes boot JSON file only when inputs change_GenerateBuildWasmBootJson(always runs) -- defines static web assets from the boot JSON outputSplit
GeneratePublishWasmBootJsoninto 2 targets:_ResolvePublishWasmBootJsonInputs(always runs) -- resolves publish endpointsGeneratePublishWasmBootJson(incremental) -- writes boot JSON only when inputs changeWebcil Conversion (commit 2)
Split
_ResolveWasmOutputsinto 3 targets:_ComputeWasmBuildCandidates(always runs) -- resolves build asset candidates viaComputeWasmBuildAssets_ConvertBuildDllsToWebcil(incremental) -- runsConvertDllsToWebcilonly when DLL inputs are newer than webcil outputs_ResolveWasmOutputs(always runs) -- reconstructs webcil items via MSBuild item transforms and callsDefineStaticWebAssetsIncrementalism Proof
Binlog analysis comparing baseline (no changes, no-op rebuild) vs PR branch (no-op rebuild with outputs up-to-date):
Key savings on incremental rebuilds:
ConvertDllsToWebciltask (~35ms) -- skipped when webcil outputs are newer than DLL inputsGenerateWasmBootJsontask (~95ms) -- skipped when boot JSON is newer than all assembly/JS inputsClean builds show negligible overhead (~1%, within noise).
Design Notes
Why split instead of just adding Inputs/Outputs?
MSBuild's
Inputs/Outputsmechanism skips the entire target body when outputs are up-to-date. Since_ResolveWasmOutputsand_GenerateBuildWasmBootJsonboth contained file-writing tasks AND item-defining tasks (DefineStaticWebAssets), making them incremental would break downstream targets that depend on the items they produce. The split separates file I/O (incremental) from item definitions (always-run).MSBuild Condition evaluation order
_ConvertBuildDllsToWebcilhasCondition="'$(_WasmEnableWebcil)' == 'true'"but MSBuild evaluatesConditionbeforeDependsOnTargets. Since_WasmEnableWebcilis set by_ResolveWasmConfiguration(inside_ComputeWasmBuildCandidates), the parent_ResolveWasmOutputsexplicitly lists_ComputeWasmBuildCandidatesin itsDependsOnTargetsbefore_ConvertBuildDllsToWebcil.Culture/non-culture DLL separation
Non-culture DLLs and culture-specific DLLs have different metadata (
RelatedAssetonly exists on culture items). Using%(RelatedAsset)in item transforms causes MSB4096 batching errors when applied to items without that metadata. The fix uses separate intermediate item names (_WasmWebcilConvertedNonCulture,_WasmWebcilConvertedCulture) to avoid cross-contamination.Testing