Skip to content

Commit d79ec02

Browse files
authored
[StaticWebAssets] Backport perf fixes (#47913)
Backports * [StaticWebAssets] Process endpoint definitions in parallel #43736 * [StaticWebAssets] Improve globbing match performance #44159 * [StaticWebAssets] Adds incrementalism to DefineStaticWebAssets #47701
1 parent 6e5cad9 commit d79ec02

File tree

97 files changed

+12100
-4062
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+12100
-4062
lines changed

src/BlazorWasmSdk/Targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.props

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Copyright (c) .NET Foundation. All rights reserved.
3030
<StaticWebAssetsAdditionalPublishProperties>$(StaticWebAssetsAdditionalPublishProperties);_PublishingBlazorWasmProject=true</StaticWebAssetsAdditionalPublishProperties>
3131
<StaticWebAssetsAdditionalEmbeddedPublishProperties>$(StaticWebAssetsAdditionalEmbeddedPublishProperties);_PublishingBlazorWasmProject=true</StaticWebAssetsAdditionalEmbeddedPublishProperties>
3232
<StaticWebAssetStandaloneHosting Condition="'$(StaticWebAssetStandaloneHosting)' == '' and '$(StaticWebAssetProjectMode)' == 'Root'">true</StaticWebAssetStandaloneHosting>
33+
<StaticWebAssetMakeReferencedAssetOriginalItemSpecAbsolute Condition="'$(StaticWebAssetMakeReferencedAssetOriginalItemSpecAbsolute)' == ''">true</StaticWebAssetMakeReferencedAssetOriginalItemSpecAbsolute>
3334
<StaticWebAssetsGetEmbeddedPublishAssetsTargets>ComputeFilesToPublish;GetCurrentProjectEmbeddedPublishStaticWebAssetItems</StaticWebAssetsGetEmbeddedPublishAssetsTargets>
3435
</PropertyGroup>
3536

src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.Compression.targets

+6-3
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,20 @@ Copyright (c) .NET Foundation. All rights reserved.
219219
<!-- Build -->
220220

221221
<Target Name="ResolveBuildCompressedStaticWebAssets" DependsOnTargets="$(ResolveBuildCompressedStaticWebAssetsDependsOn)">
222+
223+
<PropertyGroup>
224+
<_ResolveBuildCompressedStaticWebAssetsCachePath>$(_StaticWebAssetsManifestBase)rbcswa.dswa.cache.json</_ResolveBuildCompressedStaticWebAssetsCachePath>
225+
</PropertyGroup>
226+
222227
<DefineStaticWebAssets
223228
CandidateAssets="@(_CompressedStaticWebAssets)"
229+
CacheManifestPath="$(_ResolveBuildCompressedStaticWebAssetsCachePath)"
224230
>
225231
<Output TaskParameter="Assets" ItemName="_CompressionBuildStaticWebAsset" />
226-
<Output TaskParameter="AssetDetails" ItemName="_ResolveBuildCompressedStaticWebAssetsDetails" />
227232
</DefineStaticWebAssets>
228233

229234
<DefineStaticWebAssetEndpoints
230235
CandidateAssets="@(_CompressionBuildStaticWebAsset);@(_PrecompressedStaticWebAssets)"
231-
ExistingEndpoints="@(StaticWebAssetEndpoint)"
232236
ContentTypeMappings="@(StaticWebAssetContentTypeMapping)"
233237
>
234238
<Output TaskParameter="Endpoints" ItemName="_CompressionBuildStaticWebAssetEndpoint" />
@@ -242,7 +246,6 @@ Copyright (c) .NET Foundation. All rights reserved.
242246

243247
<ApplyCompressionNegotiation
244248
CandidateEndpoints="@(StaticWebAssetEndpoint)"
245-
AssetFileDetails="@(_ResolveBuildCompressedStaticWebAssetsDetails)"
246249
CandidateAssets="@(_CompressionCurrentProjectBuildAssets)"
247250
>
248251
<Output TaskParameter="UpdatedEndpoints" ItemName="_UpdatedCompressionBuildEndpoints" />

src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.JSModules.targets

+17-2
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,19 @@ Copyright (c) .NET Foundation. All rights reserved.
9898
to identify them and correctly clasify them. Modules from other projects or packages will already be correctly tagged when we
9999
retrieve them.
100100
-->
101+
102+
<PropertyGroup>
103+
<_ResolveJsInitializerModuleStaticWebAssetsCachePath>$(_StaticWebAssetsManifestBase)rjimswa.dswa.cache.json</_ResolveJsInitializerModuleStaticWebAssetsCachePath>
104+
</PropertyGroup>
105+
101106
<DefineStaticWebAssets Condition="@(_JSModuleCandidates) != ''"
102107
CandidateAssets="@(_JSModuleCandidates)"
103108
AssetTraitName="JSModule"
104109
AssetTraitValue="JSLibraryModule"
105110
RelativePathFilter="**/$(PackageId).lib.module.js"
106111
PropertyOverrides="AssetTraitName;AssetTraitValue"
107112
AssetMergeSource="$(StaticWebAssetMergeTarget)"
113+
CacheManifestPath="$(_ResolveJsInitializerModuleStaticWebAssetsCachePath)"
108114
>
109115
<Output TaskParameter="Assets" ItemName="_JSModuleStaticWebAsset" />
110116
</DefineStaticWebAssets>
@@ -404,6 +410,13 @@ Copyright (c) .NET Foundation. All rights reserved.
404410
<_JSFileModuleCandidates Include="@(_JSFileModuleNoneCandidates)" />
405411
</ItemGroup>
406412

413+
<PropertyGroup>
414+
<_ResolveJSModuleStaticWebAssetsRazorCachePath>$(_StaticWebAssetsManifestBase)rjsmrazor.dswa.cache.json</_ResolveJSModuleStaticWebAssetsRazorCachePath>
415+
</PropertyGroup>
416+
<PropertyGroup>
417+
<_ResolveJSModuleStaticWebAssetsCshtmlCachePath>$(_StaticWebAssetsManifestBase)rjsmcshtml.dswa.cache.json</_ResolveJSModuleStaticWebAssetsCshtmlCachePath>
418+
</PropertyGroup>
419+
407420
<!-- Find JS module files -->
408421
<!-- **/*.razor.js -->
409422
<DefineStaticWebAssets
@@ -413,7 +426,8 @@ Copyright (c) .NET Foundation. All rights reserved.
413426
ContentRoot="$(MSBuildProjectDirectory)"
414427
SourceType="Discovered"
415428
BasePath="$(StaticWebAssetBasePath)"
416-
AssetMergeSource="$(StaticWebAssetMergeTarget)">
429+
AssetMergeSource="$(StaticWebAssetMergeTarget)"
430+
CacheManifestPath="$(_ResolveJSModuleStaticWebAssetsRazorCachePath)">
417431
<Output TaskParameter="Assets" ItemName="_ComponentJSModule" />
418432
</DefineStaticWebAssets>
419433

@@ -425,7 +439,8 @@ Copyright (c) .NET Foundation. All rights reserved.
425439
ContentRoot="$(MSBuildProjectDirectory)"
426440
SourceType="Discovered"
427441
BasePath="$(StaticWebAssetBasePath)"
428-
AssetMergeSource="$(StaticWebAssetMergeTarget)">
442+
AssetMergeSource="$(StaticWebAssetMergeTarget)"
443+
CacheManifestPath="$(_ResolveJSModuleStaticWebAssetsCshtmlCachePath)">
429444
<Output TaskParameter="Assets" ItemName="_MvcJSModule" />
430445
</DefineStaticWebAssets>
431446

src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.References.targets

+2
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ Copyright (c) .NET Foundation. All rights reserved.
181181
Patterns="@(_CachedBuildStaticWebAssetDiscoveryPatterns)"
182182
ProjectMode="$(StaticWebAssetProjectMode)"
183183
AssetKind="Build"
184+
MakeReferencedAssetOriginalItemSpecAbsolute="$(StaticWebAssetMakeReferencedAssetOriginalItemSpecAbsolute)"
184185
Source="$(PackageId)"
185186
>
186187
<Output TaskParameter="StaticWebAssets" ItemName="_CachedBuildReferencedStaticWebAsset" />
@@ -227,6 +228,7 @@ Copyright (c) .NET Foundation. All rights reserved.
227228
ProjectMode="$(StaticWebAssetProjectMode)"
228229
AssetKind="Publish"
229230
Source="$(PackageId)"
231+
MakeReferencedAssetOriginalItemSpecAbsolute="$(StaticWebAssetMakeReferencedAssetOriginalItemSpecAbsolute)"
230232
>
231233
<Output TaskParameter="StaticWebAssets" ItemName="_CachedPublishReferencedStaticWebAsset" />
232234
</ComputeReferenceStaticWebAssetItems>

src/StaticWebAssetsSdk/Targets/Microsoft.NET.Sdk.StaticWebAssets.targets

+8-5
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,10 @@ Copyright (c) .NET Foundation. All rights reserved.
671671
BeforeTargets="AssignTargetPaths"
672672
DependsOnTargets="ResolveStaticWebAssetsConfiguration;UpdateExistingPackageStaticWebAssets">
673673

674+
<PropertyGroup>
675+
<_ResolveProjectStaticWebAssetsCachePath>$(_StaticWebAssetsManifestBase)rpswa.dswa.cache.json</_ResolveProjectStaticWebAssetsCachePath>
676+
</PropertyGroup>
677+
674678
<DefineStaticWebAssets
675679
CandidateAssets="@(Content)"
676680
FingerprintCandidates="$(StaticWebAssetsFingerprintContent)"
@@ -680,15 +684,14 @@ Copyright (c) .NET Foundation. All rights reserved.
680684
SourceId="$(PackageId)"
681685
ContentRoot="$(MSBuildProjectDirectory)\wwwroot\"
682686
BasePath="$(StaticWebAssetBasePath)"
683-
AssetMergeSource="$(StaticWebAssetMergeTarget)">
687+
AssetMergeSource="$(StaticWebAssetMergeTarget)"
688+
CacheManifestPath="$(_ResolveProjectStaticWebAssetsCachePath)">
684689
<Output TaskParameter="Assets" ItemName="StaticWebAsset" />
685-
<Output TaskParameter="AssetDetails" ItemName="_ResolveProjectStaticWebAssetsDetails" />
690+
<Output TaskParameter="Assets" ItemName="_CurrentProjectStaticWebAsset" />
686691
</DefineStaticWebAssets>
687692

688693
<DefineStaticWebAssetEndpoints
689-
CandidateAssets="@(StaticWebAsset)"
690-
AssetFileDetails="@(_ResolveProjectStaticWebAssetsDetails)"
691-
ExistingEndpoints="@(StaticWebAssetEndpoint)"
694+
CandidateAssets="@(_CurrentProjectStaticWebAsset)"
692695
ContentTypeMappings="@(StaticWebAssetContentTypeMapping)"
693696
>
694697
<Output TaskParameter="Endpoints" ItemName="StaticWebAssetEndpoint" />

src/StaticWebAssetsSdk/Tasks/ApplyCompressionNegotiation.cs

+2-34
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,11 @@ public class ApplyCompressionNegotiation : Task
1616
[Required]
1717
public ITaskItem[] CandidateAssets { get; set; }
1818

19-
public ITaskItem[] AssetFileDetails { get; set; }
20-
2119
[Output]
2220
public ITaskItem[] UpdatedEndpoints { get; set; }
2321

24-
public Func<string, long> TestResolveFileLength;
25-
26-
private Dictionary<string, ITaskItem> _assetFileDetails;
27-
2822
public override bool Execute()
2923
{
30-
if (AssetFileDetails != null)
31-
{
32-
_assetFileDetails = new(AssetFileDetails.Length, OSPath.PathComparer);
33-
for (int i = 0; i < AssetFileDetails.Length; i++)
34-
{
35-
var item = AssetFileDetails[i];
36-
_assetFileDetails[item.ItemSpec] = item;
37-
}
38-
}
39-
4024
var assetsById = CandidateAssets.Select(StaticWebAsset.FromTaskItem).ToDictionary(a => a.Identity);
4125

4226
var endpointsByAsset = CandidateEndpoints.Select(StaticWebAssetEndpoint.FromTaskItem)
@@ -213,24 +197,8 @@ public override bool Execute()
213197
return true;
214198
}
215199

216-
private string ResolveQuality(StaticWebAsset compressedAsset)
217-
{
218-
long length;
219-
if(_assetFileDetails != null && _assetFileDetails.TryGetValue(compressedAsset.Identity, out var assetFileDetail))
220-
{
221-
length = long.Parse(assetFileDetail.GetMetadata("FileLength"));
222-
}
223-
else if (TestResolveFileLength != null)
224-
{
225-
length = TestResolveFileLength(compressedAsset.Identity);
226-
}
227-
else
228-
{
229-
length = new FileInfo(compressedAsset.Identity).Length;
230-
}
231-
232-
return Math.Round(1.0 / (length + 1), 12).ToString("F12", CultureInfo.InvariantCulture);
233-
}
200+
private static string ResolveQuality(StaticWebAsset compressedAsset) =>
201+
Math.Round(1.0 / (compressedAsset.FileLength + 1), 12).ToString("F12", CultureInfo.InvariantCulture);
234202

235203
private static bool IsCompatible(StaticWebAssetEndpoint compressedEndpoint, StaticWebAssetEndpoint relatedEndpointCandidate)
236204
{

src/StaticWebAssetsSdk/Tasks/Compression/ResolveCompressedAssets.cs

+10-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
using System.Security.Cryptography;
55
using Microsoft.Build.Framework;
6-
using Microsoft.Extensions.FileSystemGlobbing;
76

87
namespace Microsoft.AspNetCore.StaticWebAssets.Tasks;
98

@@ -60,12 +59,15 @@ public override bool Execute()
6059
var includePatterns = SplitPattern(IncludePatterns);
6160
var excludePatterns = SplitPattern(ExcludePatterns);
6261

63-
var matcher = new Matcher();
64-
matcher.AddIncludePatterns(includePatterns);
65-
matcher.AddExcludePatterns(excludePatterns);
62+
var matcher = new StaticWebAssetGlobMatcherBuilder()
63+
.AddIncludePatterns(includePatterns)
64+
.AddExcludePatterns(excludePatterns)
65+
.Build();
6666

6767
var matchingCandidateAssets = new List<StaticWebAsset>();
6868

69+
var matchContext = StaticWebAssetGlobMatcher.CreateMatchContext();
70+
6971
// Add each candidate asset to each compression configuration with a matching pattern.
7072
foreach (var asset in candidates)
7173
{
@@ -80,9 +82,10 @@ public override bool Execute()
8082
}
8183

8284
var relativePath = asset.ComputePathWithoutTokens(asset.RelativePath);
83-
var match = matcher.Match(relativePath);
85+
matchContext.SetPathAndReinitialize(relativePath.AsSpan());
86+
var match = matcher.Match(matchContext);
8487

85-
if (!match.HasMatches)
88+
if (!match.IsMatch)
8689
{
8790
Log.LogMessage(
8891
MessageImportance.Low,
@@ -275,7 +278,7 @@ private bool TryCreateCompressedAsset(StaticWebAsset asset, string outputPath, s
275278
OriginalItemSpec = asset.Identity,
276279
RelatedAsset = asset.Identity,
277280
AssetRole = "Alternative",
278-
AssetTraitName = "Content-Encoding",
281+
AssetTraitName = "Content-Encoding",
279282
AssetTraitValue = assetTraitValue,
280283
ContentRoot = outputPath,
281284
// Set integrity and fingerprint to null so that they get recalculated for the compressed asset.

src/StaticWebAssetsSdk/Tasks/ComputeReferenceStaticWebAssetItems.cs

+10
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public class ComputeReferenceStaticWebAssetItems : Task
2323

2424
public bool UpdateSourceType { get; set; } = true;
2525

26+
public bool MakeReferencedAssetOriginalItemSpecAbsolute { get; set; }
27+
2628
[Output]
2729
public ITaskItem[] StaticWebAssets { get; set; }
2830

@@ -60,6 +62,14 @@ public override bool Execute()
6062
if (ShouldIncludeAssetAsReference(selected, out var reason))
6163
{
6264
selected.SourceType = UpdateSourceType ? StaticWebAsset.SourceTypes.Project : selected.SourceType;
65+
if (MakeReferencedAssetOriginalItemSpecAbsolute)
66+
{
67+
selected.OriginalItemSpec = Path.GetFullPath(selected.OriginalItemSpec);
68+
}
69+
else
70+
{
71+
selected.OriginalItemSpec = selected.OriginalItemSpec;
72+
}
6373
resultAssets.Add(selected);
6474
}
6575
Log.LogMessage(MessageImportance.Low, reason);

src/StaticWebAssetsSdk/Tasks/ComputeStaticWebAssetsForCurrentProject.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using Microsoft.Build.Framework;

src/StaticWebAssetsSdk/Tasks/Data/ContentTypeMapping.cs

+3-15
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Diagnostics;
5+
using System.Globalization;
56
using Microsoft.Build.Framework;
6-
using Microsoft.Extensions.FileSystemGlobbing;
77

88
namespace Microsoft.AspNetCore.StaticWebAssets.Tasks
99
{
1010
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
1111
internal struct ContentTypeMapping(string mimeType, string cache, string pattern, int priority)
1212
{
13-
private Matcher _matcher;
14-
1513
public string Pattern { get; set; } = pattern;
1614

1715
public string MimeType { get; set; } = mimeType;
@@ -24,18 +22,8 @@ internal struct ContentTypeMapping(string mimeType, string cache, string pattern
2422
contentTypeMappings.ItemSpec,
2523
contentTypeMappings.GetMetadata(nameof(Cache)),
2624
contentTypeMappings.GetMetadata(nameof(Pattern)),
27-
int.Parse(contentTypeMappings.GetMetadata(nameof(Priority))));
28-
29-
internal bool Matches(string identity)
30-
{
31-
if (_matcher == null)
32-
{
33-
_matcher = new Matcher();
34-
_matcher.AddInclude(Pattern);
35-
}
36-
return _matcher.Match(identity).HasMatches;
37-
}
25+
int.Parse(contentTypeMappings.GetMetadata(nameof(Priority)), CultureInfo.InvariantCulture));
3826

39-
private string GetDebuggerDisplay() => $"Pattern: {Pattern}, MimeType: {MimeType}, Cache: {Cache}, Priority: {Priority}";
27+
private readonly string GetDebuggerDisplay() => $"Pattern: {Pattern}, MimeType: {MimeType}, Cache: {Cache}, Priority: {Priority}";
4028
}
4129
}

0 commit comments

Comments
 (0)