ASP.NET Core Blazor gelişmiş senaryoları (işleme ağacı oluşturma)

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.

Uyarı

ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 9 sürümüne bakın.

Bu makalede, ile işleme ağaçlarını el ile RenderTreeBuilderoluşturmaya Blazor yönelik gelişmiş senaryo açıklanmaktadır.

Uyarı

RenderTreeBuilder Bileşenleri oluşturmak için kullanımı gelişmiş bir senaryodur. Hatalı biçimlendirilmiş bir bileşen (örneğin, kapatılmamış işaretleme etiketi) tanımsız davranışa neden olabilir. Tanımsız davranış bozuk içerik işlemeyi, uygulama özelliklerinin kaybını ve güvenliği tehlikeye atmış güvenliği içerir.

İşleme ağacını el ile oluşturma (RenderTreeBuilder)

RenderTreeBuilder C# kodunda bileşenleri el ile oluşturma da dahil olmak üzere bileşenleri ve öğeleri işlemek için yöntemler sağlar.

Başka bir bileşende el ile işlenebilen aşağıdaki PetDetails bileşeni göz önünde bulundurun.

PetDetails.razor:

<h2>Pet Details</h2>

<p>@PetDetailsQuote</p>

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

Aşağıdaki BuiltContent bileşende, yöntemindeki CreateComponent döngü üç PetDetails bileşen oluşturur.

Sıra RenderTreeBuilder numarası olan yöntemlerde, sıra numaraları kaynak kod satır numaralarıdır. Fark Blazor algoritması, ayrı çağrı çağrılarına değil, farklı kod satırlarına karşılık gelen sıra numaralarını kullanır. Yöntemlerle RenderTreeBuilder bir bileşen oluştururken, sıra numaraları için bağımsız değişkenleri sabit kodla. Sıra numarasını oluşturmak için bir hesaplama veya sayaç kullanmak performansın düşmesine neden olabilir. Daha fazla bilgi için Sıra numaraları yürütme sırasıyla değil kod satırı numaralarıyla ilgilidir bölümüne bakı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"

<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();
    }
}

Uyarı

içindeki Microsoft.AspNetCore.Components.RenderTree türler işleme işlemlerinin sonuçlarının işlenmesine izin verir. Bunlar çerçeve uygulamasının Blazor iç ayrıntılarıdır. Bu türler kararsız olarak kabul edilmeli ve gelecek sürümlerde değiştirilebilir.

Sıra numaraları, yürütme sırasıyla değil kod satırı numaralarıyla ilgilidir

Razor bileşen dosyaları (.razor) her zaman derlenir. Derlenmiş kodun yürütülmesi, kodu yorumlamaya göre olası bir avantaja sahiptir çünkü derlenmiş kodu veren derleme adımı çalışma zamanında uygulama performansını iyileştiren bilgiler eklemek için kullanılabilir.

Bu iyileştirmelerin önemli bir örneği sıra numaralarını içerir. Sıra numaraları, çıkışların hangi farklı ve sıralı kod satırlarından geldiğini çalışma zamanına gösterir. Çalışma zamanı, doğrusal zamanda verimli ağaç farkları oluşturmak için bu bilgileri kullanır ve bu da genel ağaç fark algoritması için normalde mümkün olandan çok daha hızlıdır.

Aşağıdaki Razor bileşen dosyasını (.razor):

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

Second

Yukarıdaki Razor işaretleme ve metin içeriği aşağıdakine benzer şekilde C# kodunda derleniyor:

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

builder.AddContent(1, "Second");

Kod ilk kez yürütür ve someFlag olduğunda true, oluşturucu aşağıdaki tabloda sırayı alır.

Sequence Tür Veri
0 Metin düğümü First
1 Metin düğümü Second

Bunun someFlag olduğunu false ve işaretlemenin yeniden işlendiğini düşünün. Bu kez, oluşturucu aşağıdaki tabloda sırayı alır.

Sequence Tür Veri
1 Metin düğümü Second

Çalışma zamanı bir fark gerçekleştirdiğinde, sıralı 0 öğenin kaldırıldığını görür, bu nedenle tek bir adımla aşağıdaki önemsiz düzenleme betiğini oluşturur:

  • İlk metin düğümünü kaldırın.

Program aracılığıyla sıra numaraları oluşturma sorunu

Bunun yerine aşağıdaki işleme ağacı oluşturucu mantığını yazdığınızı düşünün:

var seq = 0;

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

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

İlk çıkış aşağıdaki tabloya yansıtılır.

Sequence Tür Veri
0 Metin düğümü First
1 Metin düğümü Second

Bu sonuç önceki durumla aynıdır, bu nedenle olumsuz bir sorun yoktur. someFlag ikinci işlemededir false ve çıkış aşağıdaki tabloda görülmektedir.

Sequence Tür Veri
0 Metin düğümü Second

Bu kez fark algoritması iki değişikliğin gerçekleştiğini görür. Algoritma aşağıdaki düzenleme betiğini oluşturur:

  • İlk metin düğümünün değerini olarak Seconddeğiştirin.
  • İkinci metin düğümünü kaldırın.

Sıra numaralarının oluşturulması, dalların ve döngülerin özgün kodda nerede bulunduğuyla if/else ilgili tüm yararlı bilgileri kaybetti. Bu, öncekinin iki katı kadar farkla sonuçlandı.

Bu önemsiz bir örnektir. Karmaşık ve derin iç içe yapılara ve özellikle döngülere sahip daha gerçekçi durumlarda performans maliyeti genellikle daha yüksektir. Hangi döngü bloklarının veya dalların eklendiğini veya kaldırıldığını hemen belirlemek yerine fark algoritmasının işleme ağaçlarında ayrıntılı bir şekilde yinelemesi gerekir. Bu durum genellikle daha uzun düzenleme betikleri oluşturulmasına neden olur çünkü fark algoritması eski ve yeni yapıların birbiriyle ilişkisi hakkında yanlış bilgilendirilmiştir.

Rehberlik ve sonuçlar

  • Sıra numaraları dinamik olarak oluşturulursa uygulama performansı düşer.
  • Bilgiler derleme zamanında yakalanmadığı sürece çerçevenin çalışma zamanında otomatik olarak sıra numaraları oluşturmasına izin vermek için gerekli bilgiler yoktur.
  • El ile uygulanan mantığın uzun bloklarını yazmayın RenderTreeBuilder . Dosyaları tercih edin .razor ve derleyicinin sıra numaralarıyla ilgilenmesine izin verin. El ile RenderTreeBuilder mantık kullanmaktan kaçınamıyorsanız uzun kod bloklarını çağrılarda OpenRegion/CloseRegion sarmalanmış daha küçük parçalara ayırın. Her bölgenin ayrı sıra numaraları alanı vardır, bu nedenle her bölgenin içinde sıfırdan (veya başka herhangi bir rastgele sayıdan) yeniden başlatabilirsiniz.
  • Sıra numaraları sabit kodlanmışsa, fark algoritması yalnızca dizi numaralarının değer olarak artırılmasını gerektirir. İlk değer ve boşluklar ilgisizdir. Geçerli bir seçenek, kod satırı numarasını sıra numarası olarak kullanmak veya sıfırdan başlayıp bir veya yüzlerce (veya tercih edilen aralık) ile artırmaktır.
  • Döngüler için, sıra numaraları çalışma zamanı davranışı açısından değil kaynak kodunuzda artmalıdır. Çalışma zamanında sayıların tekrarlanması fark sisteminin döngüde olduğunuzu fark etme şeklidir.
  • Blazor sıra numaralarını kullanırken, diğer ağaç fark eden kullanıcı arabirimi çerçeveleri bunları kullanmaz. Sıralama numaraları kullanıldığında fark çok daha hızlıdır ve Blazor dosyaları yazan .razor geliştiriciler için sıra numaralarıyla otomatik olarak ilgilenen bir derleme adımının avantajına sahiptir.