109 lines
4.1 KiB
C#
109 lines
4.1 KiB
C#
// 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;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using BenchmarkDotNet.Attributes;
|
|
using Microsoft.AspNetCore.Blazor.Components;
|
|
using Microsoft.AspNetCore.Blazor.Rendering;
|
|
using Microsoft.AspNetCore.Blazor.RenderTree;
|
|
|
|
namespace Microsoft.AspNetCore.Blazor.Performance
|
|
{
|
|
public class RenderTreeDiffBuilderBenchmark
|
|
{
|
|
private readonly Renderer renderer;
|
|
private readonly RenderTreeBuilder original;
|
|
private readonly RenderTreeBuilder modified;
|
|
private readonly RenderBatchBuilder builder;
|
|
|
|
public RenderTreeDiffBuilderBenchmark()
|
|
{
|
|
builder = new RenderBatchBuilder();
|
|
renderer = new FakeRenderer();
|
|
|
|
// A simple component for basic tests -- this is similar to what MVC scaffolding generates
|
|
// for bootstrap3 form fields, but modified to be more Blazorey.
|
|
original = new RenderTreeBuilder(renderer);
|
|
original.OpenElement(0, "div");
|
|
original.AddAttribute(1, "class", "form-group");
|
|
|
|
original.OpenElement(2, "label");
|
|
original.AddAttribute(3, "class", "control-label");
|
|
original.AddAttribute(4, "for", "name");
|
|
original.AddAttribute(5, "data-unvalidated", true);
|
|
original.AddContent(6, "Car");
|
|
original.CloseElement();
|
|
|
|
original.OpenElement(7, "input");
|
|
original.AddAttribute(8, "class", "form-control");
|
|
original.AddAttribute(9, "type", "text");
|
|
original.AddAttribute(10, "name", "name"); // Notice the gap in sequence numbers
|
|
original.AddAttribute(12, "value", "");
|
|
original.CloseElement();
|
|
|
|
original.OpenElement(13, "span");
|
|
original.AddAttribute(14, "class", "text-danger field-validation-valid");
|
|
original.AddContent(15, "");
|
|
original.CloseElement();
|
|
|
|
original.CloseElement();
|
|
|
|
// Now simulate some input
|
|
modified = new RenderTreeBuilder(renderer);
|
|
modified.OpenElement(0, "div");
|
|
modified.AddAttribute(1, "class", "form-group");
|
|
|
|
modified.OpenElement(2, "label");
|
|
modified.AddAttribute(3, "class", "control-label");
|
|
modified.AddAttribute(4, "for", "name");
|
|
modified.AddAttribute(5, "data-unvalidated", false);
|
|
modified.AddContent(6, "Car");
|
|
modified.CloseElement();
|
|
|
|
modified.OpenElement(7, "input");
|
|
modified.AddAttribute(8, "class", "form-control");
|
|
modified.AddAttribute(9, "type", "text");
|
|
modified.AddAttribute(10, "name", "name");
|
|
modified.AddAttribute(11, "data-validation-state", "invalid");
|
|
modified.AddAttribute(12, "value", "Lamborghini");
|
|
modified.CloseElement();
|
|
|
|
modified.OpenElement(13, "span");
|
|
modified.AddAttribute(14, "class", "text-danger field-validation-invalid"); // changed
|
|
modified.AddContent(15, "No, you can't afford that.");
|
|
modified.CloseElement();
|
|
|
|
modified.CloseElement();
|
|
}
|
|
|
|
[Benchmark(Description = "RenderTreeDiffBuilder: Input and validation on a single form field.", Baseline = true)]
|
|
public void ComputeDiff_SingleFormField()
|
|
{
|
|
builder.Clear();
|
|
var diff = RenderTreeDiffBuilder.ComputeDiff(renderer, builder, 0, original.GetFrames(), modified.GetFrames());
|
|
GC.KeepAlive(diff);
|
|
}
|
|
|
|
private class FakeRenderer : Renderer
|
|
{
|
|
public FakeRenderer()
|
|
: base(new TestServiceProvider())
|
|
{
|
|
}
|
|
|
|
protected override Task UpdateDisplayAsync(in RenderBatch renderBatch)
|
|
=> Task.CompletedTask;
|
|
}
|
|
|
|
private class TestServiceProvider : IServiceProvider
|
|
{
|
|
public object GetService(Type serviceType)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|