From dotnet-msbuild
Diagnose MSBuild build performance bottlenecks using binary log analysis. Only activate in MSBuild/.NET build context. USE FOR: identifying why builds are slow by analyzing binlog performance summaries, detecting ResolveAssemblyReference (RAR) taking >5s, Roslyn analyzers consuming >30% of Csc time, single targets dominating >50% of build time, node utilization below 80%, excessive Copy tasks, NuGet restore running every build. Covers timeline analysis, Target/Task Performance Summary interpretation, and 7 common bottleneck categories. Use after build-perf-baseline has established measurements. DO NOT USE FOR: establishing initial baselines (use build-perf-baseline first), fixing incremental build issues (use incremental-build), parallelism tuning (use build-parallelism), non-MSBuild build systems. INVOKES: binlog MCP server tools (overview, errors, search, items, properties); falls back to dotnet msbuild binlog replay + grep/cat when the MCP is unavailable.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dotnet-msbuild:build-perf-diagnosticsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
1. **Generate a binlog**: `dotnet build /bl:{} -m`
dotnet build /bl:{} -mMicrosoft.AITools.BinlogMcp, exposed under the binlog MCP namespace) which is bundled with this plugindotnet build /bl:{} -mdotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log;performancesummary
full.log):
grep "Target Performance Summary\|Task Performance Summary" -A 50 full.log
grep -i "node.*assigned\|building with\|scheduler" full.log | head -30
grep -i "analyzer.*elapsed\|Total analyzer execution time\|CompilerAnalyzerDriver" full.log
<DesignTimeBuild>false</DesignTimeBuild> for RAR-heavy analysis, set <ResolveAssemblyReferencesSilent>true</ResolveAssemblyReferencesSilent> for diagnostic<DesignTimeBuild> and <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch><DisableTransitiveProjectReferences>true</DisableTransitiveProjectReferences> to avoid pulling in the full transitive closure (note: projects may need to add direct references for any types they consume). Use ReferenceOutputAssembly="false" on ProjectReferences that are only needed at build time (not API surface). Trim unused PackageReferences./p:RunAnalyzers=false)<RunAnalyzers Condition="'$(ContinuousIntegrationBuild)' != 'true'">false</RunAnalyzers><RunAnalyzers Condition="'$(Configuration)' == 'Debug'">false</RunAnalyzers><EnforceCodeStyleInBuild Condition="'$(ContinuousIntegrationBuild)' == 'true'">true</EnforceCodeStyleInBuild>GlobalPackageReference in Directory.Packages.props apply to ALL projects. Consider if test projects need the same analyzer set as production code.true in Directory.Build.props, forces code-style analysis on every build. Should be conditional on CI environment (ContinuousIntegrationBuild) to avoid slowing dev inner loop.BuildInParallel<CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>true</CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>), reduce CopyToOutputDirectory items, use <UseCommonOutputDirectory>true</UseCommonOutputDirectory> when appropriate, set <SkipCopyUnchangedFiles>true</SkipCopyUnchangedFiles>, consider --artifacts-path (.NET 8+) for centralized output layout<EnableDefaultItems>false</EnableDefaultItems> for legacy projects with explicit file lists, avoid NuGet-based SDK resolvers if possibleeval-performance skill for detailed guidancedotnet restore then dotnet build --no-restore<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation> in Directory.Build.props — can save significant time in large builds (results are workload-dependent)/graph mode for better schedulingStep-by-step workflow using text log replay:
dotnet msbuild build.binlog -noconlog -fl -flp:v=diag;logfile=full.log;performancesummary
full.log):
grep "Target Performance Summary\|Task Performance Summary" -A 50 full.log
This shows all targets and tasks sorted by cumulative time — equivalent to finding expensive targets/tasks.grep "done building project\|Project Performance Summary" full.log
grep -i "node.*assigned\|RequiresLeadingNewline\|Building with" full.log | head -30
grep -i "Total analyzer execution time\|analyzer.*elapsed\|CompilerAnalyzerDriver" full.log
grep 'Target "CoreCompile"\|Target "ResolveAssemblyReferences"' full.log
/maxcpucount (or -m) for parallel buildsdotnet restore then dotnet build --no-restore)<RestoreUseStaticGraphEvaluation>true</RestoreUseStaticGraphEvaluation>)<CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>true</CreateHardLinksForCopyFilesToOutputDirectoryIfPossible>)<RunAnalyzers Condition="'$(ContinuousIntegrationBuild)' != 'true'">false</RunAnalyzers><ProduceReferenceAssembly>true</ProduceReferenceAssembly>)incremental-build skill)check-bin-obj-clash skill)/graph) for multi-project solutions--artifacts-path (.NET 8+) for centralized output layoutWhen reporting findings, categorize by impact to help prioritize fixes:
Provides a checklist for code reviews covering functionality, security, performance, maintainability, tests, and quality. Use for pull requests, audits, team standards, and developer training.
npx claudepluginhub weiflycc-cmd/skills --plugin dotnet-msbuild