Sdílet prostřednictvím


pokročilé scénáře ASP.NET Core Blazor (vytváření stromové struktury)

Poznámka:

Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Upozorňující

Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Důležité

Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.

Aktuální verzi najdete ve verzi .NET 8 tohoto článku.

Tento článek popisuje pokročilý scénář pro ruční vytváření Blazor stromů vykreslování pomocí RenderTreeBuilder.

Upozorňující

RenderTreeBuilder Použití k vytvoření komponent je pokročilý scénář. Nedefinovaná komponenta (například nezařazená značka značek) může mít za následek nedefinované chování. Nedefinované chování zahrnuje poškozené vykreslování obsahu, ztrátu funkcí aplikace a ohrožení zabezpečení.

Ruční sestavení stromu vykreslování (RenderTreeBuilder)

RenderTreeBuilder poskytuje metody pro manipulaci s komponentami a prvky, včetně ručního sestavování součástí v kódu jazyka C#.

Představte si následující PetDetails komponentu, kterou lze ručně vykreslit v jiné komponentě.

PetDetails.razor:

<h2>Pet Details</h2>

<p>@PetDetailsQuote</p>

@code
{
    [Parameter]
    public string? PetDetailsQuote { get; set; }
}

V následující BuiltContent komponentě smyčka v CreateComponent metodě generuje tři PetDetails komponenty.

V RenderTreeBuilder metodách s pořadovým číslem jsou pořadová čísla řádky zdrojového kódu. Algoritmus Blazor rozdílu spoléhá na pořadová čísla odpovídající odlišným řádkům kódu, nikoli k odlišným voláním. Při vytváření komponenty s metodami RenderTreeBuilder pevně zakódujte argumenty pro pořadová čísla. Použití výpočtu nebo čítače ke generování pořadového čísla může vést k nízkému výkonu. Další informace najdete v části Pořadová čísla související s čísly řádků kódu, nikoli oddílem pořadí provádění.

BuiltContent.razor:

@page "/built-content"

<PageTitle>Built Content</PageTitle>

<h1>Built Content Example</h1>

<div>
    @CustomRender
</div>

<button @onclick="RenderComponent">
    Create three Pet Details components
</button>

@code {
    private RenderFragment? CustomRender { get; set; }

    private RenderFragment CreateComponent() => builder =>
    {
        for (var i = 0; i < 3; i++) 
        {
            builder.OpenComponent(0, typeof(PetDetails));
            builder.AddAttribute(1, "PetDetailsQuote", "Someone's best friend!");
            builder.CloseComponent();
        }
    };

    private void RenderComponent()
    {
        CustomRender = CreateComponent();
    }
}
@page "/built-content"

<h1>Build a component</h1>

<div>
    @CustomRender
</div>

<button @onclick="RenderComponent">
    Create three Pet Details components
</button>

@code {
    private RenderFragment? CustomRender { get; set; }

    private RenderFragment CreateComponent() => builder =>
    {
        for (var i = 0; i < 3; i++) 
        {
            builder.OpenComponent(0, typeof(PetDetails));
            builder.AddAttribute(1, "PetDetailsQuote", "Someone's best friend!");
            builder.CloseComponent();
        }
    };

    private void RenderComponent()
    {
        CustomRender = CreateComponent();
    }
}

Upozorňující

Typy, které Microsoft.AspNetCore.Components.RenderTree umožňují zpracování výsledků operací vykreslování. Jedná se o interní podrobnosti implementace Blazor architektury. Tyto typy by se měly považovat za nestabilní a v budoucích verzích by se měly měnit.

Pořadová čísla souvisejí s čísly řádků kódu a ne pořadím provádění.

Razor soubory komponent (.razor) se vždy kompilují. Spouštění zkompilovaného kódu má potenciální výhodu při interpretaci kódu, protože krok kompilace, který zkompilovaný kód přináší, lze použít k vložení informací, které zlepšují výkon aplikace za běhu.

Klíčovým příkladem těchto vylepšení jsou pořadová čísla. Pořadová čísla označují modul runtime, ze kterého výstupy pocházejí, z nichž různé a seřazené řádky kódu pocházejí. Modul runtime používá tyto informace ke generování efektivních rozdílů stromu v lineárním čase, což je mnohem rychlejší, než je obvykle možné pro obecný algoritmus rozdílu stromu.

Zvažte následující Razor soubor komponenty (.razor):

@if (someFlag)
{
    <text>First</text>
}

Second

Předchozí Razor kód a textový obsah se zkompiluje do kódu jazyka C#, který je podobný následujícímu:

if (someFlag)
{
    builder.AddContent(0, "First");
}

builder.AddContent(1, "Second");

Při prvním spuštění kódu a someFlag je true, tvůrce obdrží posloupnost v následující tabulce.

Sequence Typ Data
0 Textový uzel První
0 Textový uzel Second

Představte si, že se someFlag kód stane false a znovu se vykreslí. Tentokrát tvůrce obdrží sekvenci v následující tabulce.

Sequence Typ Data
0 Textový uzel Second

Když modul runtime provede rozdíl, zjistí, že položka v sekvenci 0 byla odebrána, takže vygeneruje následující triviální skript pro úpravy jedním krokem:

  • Odeberte první textový uzel.

Problém se generováním pořadových čísel prostřednictvím kódu programu

Představte si místo toho, že jste napsali následující logiku tvůrce stromové struktury vykreslování:

var seq = 0;

if (someFlag)
{
    builder.AddContent(seq++, "First");
}

builder.AddContent(seq++, "Second");

První výstup se odráží v následující tabulce.

Sequence Typ Data
0 Textový uzel První
0 Textový uzel Second

Tento výsledek je identický s předchozím případem, takže neexistují žádné negativní problémy. someFlag je false na druhém vykreslování a výstup se zobrazí v následující tabulce.

Sequence Typ Data
0 Textový uzel Second

Tentokrát rozdílový algoritmus zjistí, že došlo ke dvěma změnám. Algoritmus vygeneruje následující skript pro úpravy:

  • Změňte hodnotu prvního textového uzlu na Second.
  • Odeberte druhý textový uzel.

Generování pořadových čísel ztratilo všechny užitečné informace o tom, kde if/else byly větve a smyčky přítomny v původním kódu. Výsledkem je rozdíl dvakrát tak dlouho jako předtím.

Toto je triviální příklad. V realističtějších případech se složitými a hluboce vnořenými strukturami, a zejména se smyčkami, jsou náklady na výkon obvykle vyšší. Místo okamžité identifikace bloků smyčky nebo větví, které byly vloženy nebo odebrány, musí algoritmus rozdílu hluboko zabrat do vykreslovaných stromů. To obvykle vede k vytvoření delších skriptů pro úpravy, protože algoritmus rozdílu je nesprávně informován o tom, jak staré a nové struktury vzájemně souvisejí.

Pokyny a závěry

  • Výkon aplikace trpí tím, že se pořadová čísla generují dynamicky.
  • Architektura nemůže automaticky vytvořit vlastní pořadová čísla za běhu, protože potřebné informace neexistují, pokud nejsou zachyceny v době kompilace.
  • Nezapisujte dlouhé bloky ručně implementované RenderTreeBuilder logiky. Upřednostňujte .razor soubory a povolte kompilátoru pracovat s pořadovými čísly. Pokud se nemůžete vyhnout ruční RenderTreeBuilder logice, rozdělte dlouhé bloky kódu na menší části zabalené do OpenRegion/CloseRegion volání. Každá oblast má svůj vlastní samostatný prostor sekvenčních čísel, takže můžete restartovat z nuly (nebo jakéhokoli jiného libovolného čísla) v každé oblasti.
  • Pokud jsou pořadová čísla pevně zakódovaná, algoritmus rozdílu vyžaduje pouze zvýšení hodnoty pořadových čísel. Počáteční hodnota a mezery jsou irelevantní. Jednou z legitimních možností je použít číslo řádku kódu jako pořadové číslo nebo začít od nuly a zvýšit je o jednu nebo stovky (nebo libovolný upřednostňovaný interval).
  • U smyček by se pořadová čísla měla zvýšit ve zdrojovém kódu, ne z hlediska chování modulu runtime. Skutečnost, že za běhu se čísla opakují, je způsob, jakým rozdílový systém uvědomuje, že jste ve smyčce.
  • Blazor používá pořadová čísla, zatímco jiné architektury uživatelského rozhraní využívající stromové rozdíly je nepoužívají. Rozdíl je při použití pořadových čísel mnohem rychlejší a Blazor má výhodu kroku kompilace, který se automaticky zabývá pořadovými čísly pro vývojáře, kteří .razor vytváří soubory.