Blazor.WhyDidYouRender 1.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package Blazor.WhyDidYouRender --version 1.0.1
                    
NuGet\Install-Package Blazor.WhyDidYouRender -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Blazor.WhyDidYouRender" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Blazor.WhyDidYouRender" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Blazor.WhyDidYouRender" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Blazor.WhyDidYouRender --version 1.0.1
                    
#r "nuget: Blazor.WhyDidYouRender, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Blazor.WhyDidYouRender@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Blazor.WhyDidYouRender&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Blazor.WhyDidYouRender&version=1.0.1
                    
Install as a Cake Tool

Blazor WhyDidYouRender

A powerful performance monitoring and debugging tool for Blazor applications that helps identify unnecessary re-renders and optimize component performance.

🚀 Features

  • 🔍 Render Tracking: Monitor when and why your Blazor components re-render
  • 📊 Performance Metrics: Track render duration and frequency
  • 🎯 Parameter Change Detection: Identify which parameter changes trigger re-renders
  • ⚡ Unnecessary Render Detection: Find components that re-render without actual changes
  • 🛠️ Developer-Friendly: Easy integration with existing Blazor applications
  • 📱 Browser Console Logging: Real-time debugging information in browser dev tools
  • ⚙️ Configurable: Flexible configuration options for different environments
  • 🔧 Diagnostics Endpoint: Optional HTTP endpoint for advanced monitoring

📦 Installation

Package Manager Console

Install-Package Blazor.WhyDidYouRender

.NET CLI

dotnet add package Blazor.WhyDidYouRender

PackageReference

<PackageReference Include="Blazor.WhyDidYouRender" Version="1.0.0" />

🛠️ Quick Start

1. Register Services

Add WhyDidYouRender to your service collection in Program.cs:

using Blazor.WhyDidYouRender.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add Blazor services
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();

// Add WhyDidYouRender
builder.Services.AddWhyDidYouRender(config =>
{
    config.Enabled = true;
    config.Verbosity = TrackingVerbosity.Normal;
    config.Output = TrackingOutput.Both; // Server console AND browser console
    config.TrackParameterChanges = true;
    config.TrackPerformance = true;
});

var app = builder.Build();

// Initialize WhyDidYouRender SSR services
app.Services.InitializeSSRServices();

// Configure pipeline...
app.Run();

2. Inherit from TrackedComponentBase

Update your components to inherit from TrackedComponentBase:

@using Blazor.WhyDidYouRender.Components
@using Blazor.WhyDidYouRender.Extensions
@inherits TrackedComponentBase
@inject IJSRuntime JSRuntime
@inject IServiceProvider ServiceProvider

<h3>My Tracked Component</h3>
<p>Current count: @currentCount</p>
<button @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;
    private bool browserLoggerInitialized = false;

    [Parameter] public string? Title { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender && !browserLoggerInitialized)
        {
            // Initialize WhyDidYouRender browser logging
            await ServiceProvider.InitializeWhyDidYouRenderAsync(JSRuntime);
            browserLoggerInitialized = true;
        }
        await base.OnAfterRenderAsync(firstRender);
    }

    private void IncrementCount()
    {
        currentCount++;
    }
}

3. Monitor in Browser Console

Open your browser's developer tools and watch the console for render tracking information:

[WhyDidYouRender] Counter re-rendered
├─ Trigger: StateHasChanged
├─ Duration: 2.3ms
├─ Parameters: Title (unchanged)
└─ Reason: Manual state change

📖 Configuration

Basic Configuration

builder.Services.AddWhyDidYouRender(config =>
{
    // Enable/disable tracking
    config.Enabled = true;

    // Set logging verbosity (Minimal, Normal, Verbose)
    config.Verbosity = TrackingVerbosity.Normal;

    // Set output destination (Console, BrowserConsole, Both)
    config.Output = TrackingOutput.Both;

    // Track parameter changes
    config.TrackParameterChanges = true;

    // Track performance metrics
    config.TrackPerformance = true;

    // Include session information
    config.IncludeSessionInfo = true;
});

Advanced Configuration

builder.Services.AddWhyDidYouRender(config =>
{
    // Performance tracking
    config.TrackPerformance = true;

    // Track parameter changes
    config.TrackParameterChanges = true;

    // Include session information in logs
    config.IncludeSessionInfo = true;

    // Set verbosity level
    config.Verbosity = TrackingVerbosity.Verbose;

    // Output to both server console and browser console
    config.Output = TrackingOutput.Both;
});

Environment-Specific Configuration

builder.Services.AddWhyDidYouRender(config =>
{
    if (builder.Environment.IsDevelopment())
    {
        config.Enabled = true;
        config.Verbosity = TrackingVerbosity.Verbose;
        config.Output = TrackingOutput.Both;
        config.TrackParameterChanges = true;
        config.TrackPerformance = true;
    }
    else if (builder.Environment.IsStaging())
    {
        config.Enabled = true;
        config.Verbosity = TrackingVerbosity.Normal;
        config.Output = TrackingOutput.Console;
    }
    else
    {
        config.Enabled = false; // Disable in production
    }
});

🎯 Usage Patterns

Component Inheritance

The recommended approach is to inherit from TrackedComponentBase:

@inherits TrackedComponentBase

@code {
    // Your component logic here
}

Manual Tracking (Advanced)

For existing components that can't inherit from TrackedComponentBase, you can use manual tracking:

@inject RenderTrackerService RenderTracker

@code {
    protected override void OnAfterRender(bool firstRender)
    {
        RenderTracker.TrackRender(this, "OnAfterRender", firstRender);
        base.OnAfterRender(firstRender);
    }
}

📊 Understanding the Output

Console Log Format

[WhyDidYouRender] ComponentName re-rendered
├─ Trigger: OnParametersSet
├─ Duration: 1.2ms
├─ Parameters: 
│  ├─ Title: "Old Value" → "New Value" (changed)
│  └─ Count: 5 (unchanged)
├─ Performance: 
│  ├─ Render Count: 3
│  └─ Average Duration: 1.8ms
└─ Reason: Parameter change detected

Log Levels

  • Debug: All render events and detailed information
  • Info: Normal render events with basic information
  • Warning: Potentially unnecessary re-renders
  • Error: Performance issues and problems

🔧 Diagnostics Endpoint

Enable the optional diagnostics endpoint for advanced monitoring:

// In Program.cs
app.UseWhyDidYouRenderDiagnostics("/diagnostics/renders");

Access diagnostics at: https://yourapp.com/diagnostics/renders

🎨 Best Practices

1. Use in Development Only

config.Enabled = builder.Environment.IsDevelopment();

2. Focus on Important Events

config.Verbosity = TrackingVerbosity.Normal;
config.TrackParameterChanges = true;

3. Selective Component Tracking

Only track components you're optimizing:

// Only inherit from TrackedComponentBase for components under investigation
@inherits TrackedComponentBase

4. Parameter Optimization

Use the insights to optimize parameter passing:

// Before: Creates new object every render
<ChildComponent Data="@(new { Count = count })" />

// After: Stable reference
<ChildComponent Data="@stableDataObject" />

🚧 Roadmap

  • Testing Suite: Comprehensive test coverage (waiting for .NET 9.0 compatibility)
  • Performance Profiler: Advanced performance analysis tools
  • Custom Formatters: Extensible output formatting

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

📄 License

This project is licensed under the GNU General Public License v3.0 or later - see the LICENSE file for details.

🙏 Acknowledgments

Inspired by the React why-did-you-render library.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Blazor.WhyDidYouRender:

Package Downloads
VaultForce.SharedClient

shared resources

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.1.1 411 8/3/2025
2.1.0 127 7/30/2025
2.0.0 185 7/27/2025
1.0.1 126 7/27/2025
1.0.0 129 7/26/2025

Initial release of Blazor WhyDidYouRender - Performance monitoring and debugging tool for Blazor applications.