forked from dotnet/aspnetcore
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize render tree building via RenderTreeFrameArrayBuilder (dotnet…
- Loading branch information
1 parent
749450a
commit 38e166f
Showing
8 changed files
with
401 additions
and
238 deletions.
There are no files selected for viewing
This file contains 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
141 changes: 71 additions & 70 deletions
141
src/Components/Components/src/RenderTree/RenderTreeDiffBuilder.cs
Large diffs are not rendered by default.
Oops, something went wrong.
176 changes: 103 additions & 73 deletions
176
src/Components/Components/src/RenderTree/RenderTreeFrame.cs
Large diffs are not rendered by default.
Oops, something went wrong.
137 changes: 137 additions & 0 deletions
137
src/Components/Components/src/RenderTree/RenderTreeFrameArrayBuilder.cs
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
|
||
namespace Microsoft.AspNetCore.Components.RenderTree | ||
{ | ||
/// <summary> | ||
/// A special subclass of <see cref="ArrayBuilder{T}"/> that contains methods optimized for appending <see cref="RenderTreeFrame"/> entries. | ||
/// </summary> | ||
internal class RenderTreeFrameArrayBuilder : ArrayBuilder<RenderTreeFrame> | ||
{ | ||
// You may notice a repeated block at the top of each of these methods. This is intentionally inlined into each | ||
// method because doing so improves intensive rendering scenarios by around 1% (based on the FastGrid benchmark). | ||
|
||
public void AppendElement(int sequence, string elementName) | ||
{ | ||
if (_itemsInUse == _items.Length) | ||
{ | ||
GrowBuffer(_items.Length * 2); | ||
} | ||
|
||
_items[_itemsInUse++] = new RenderTreeFrame | ||
{ | ||
SequenceField = sequence, | ||
FrameTypeField = RenderTreeFrameType.Element, | ||
ElementNameField = elementName, | ||
}; | ||
} | ||
|
||
public void AppendText(int sequence, string textContent) | ||
{ | ||
if (_itemsInUse == _items.Length) | ||
{ | ||
GrowBuffer(_items.Length * 2); | ||
} | ||
|
||
_items[_itemsInUse++] = new RenderTreeFrame | ||
{ | ||
SequenceField = sequence, | ||
FrameTypeField = RenderTreeFrameType.Text, | ||
TextContentField = textContent, | ||
}; | ||
} | ||
|
||
public void AppendMarkup(int sequence, string markupContent) | ||
{ | ||
if (_itemsInUse == _items.Length) | ||
{ | ||
GrowBuffer(_items.Length * 2); | ||
} | ||
|
||
_items[_itemsInUse++] = new RenderTreeFrame | ||
{ | ||
SequenceField = sequence, | ||
FrameTypeField = RenderTreeFrameType.Markup, | ||
MarkupContentField = markupContent, | ||
}; | ||
} | ||
|
||
public void AppendAttribute(int sequence, string attributeName, object? attributeValue) | ||
{ | ||
if (_itemsInUse == _items.Length) | ||
{ | ||
GrowBuffer(_items.Length * 2); | ||
} | ||
|
||
_items[_itemsInUse++] = new RenderTreeFrame | ||
{ | ||
SequenceField = sequence, | ||
FrameTypeField = RenderTreeFrameType.Attribute, | ||
AttributeNameField = attributeName, | ||
AttributeValueField = attributeValue, | ||
}; | ||
} | ||
|
||
public void AppendComponent(int sequence, Type componentType) | ||
{ | ||
if (_itemsInUse == _items.Length) | ||
{ | ||
GrowBuffer(_items.Length * 2); | ||
} | ||
|
||
_items[_itemsInUse++] = new RenderTreeFrame | ||
{ | ||
SequenceField = sequence, | ||
FrameTypeField = RenderTreeFrameType.Component, | ||
ComponentTypeField = componentType, | ||
}; | ||
} | ||
|
||
public void AppendElementReferenceCapture(int sequence, Action<ElementReference> elementReferenceCaptureAction) | ||
{ | ||
if (_itemsInUse == _items.Length) | ||
{ | ||
GrowBuffer(_items.Length * 2); | ||
} | ||
|
||
_items[_itemsInUse++] = new RenderTreeFrame | ||
{ | ||
SequenceField = sequence, | ||
FrameTypeField = RenderTreeFrameType.ElementReferenceCapture, | ||
ElementReferenceCaptureActionField = elementReferenceCaptureAction, | ||
}; | ||
} | ||
|
||
public void AppendComponentReferenceCapture(int sequence, Action<object?> componentReferenceCaptureAction, int parentFrameIndexValue) | ||
{ | ||
if (_itemsInUse == _items.Length) | ||
{ | ||
GrowBuffer(_items.Length * 2); | ||
} | ||
|
||
_items[_itemsInUse++] = new RenderTreeFrame | ||
{ | ||
SequenceField = sequence, | ||
FrameTypeField = RenderTreeFrameType.ComponentReferenceCapture, | ||
ComponentReferenceCaptureActionField = componentReferenceCaptureAction, | ||
ComponentReferenceCaptureParentFrameIndexField = parentFrameIndexValue, | ||
}; | ||
} | ||
|
||
public void AppendRegion(int sequence) | ||
{ | ||
if (_itemsInUse == _items.Length) | ||
{ | ||
GrowBuffer(_items.Length * 2); | ||
} | ||
|
||
_items[_itemsInUse++] = new RenderTreeFrame | ||
{ | ||
SequenceField = sequence, | ||
FrameTypeField = RenderTreeFrameType.Region, | ||
}; | ||
} | ||
} | ||
} |
This file contains 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
Oops, something went wrong.