Should I use OnAfterRenderAsync instead of OnInitializedAsync?

Viewed 731

In a Blazor server component, I use OnInitializedAsync() to connect an event from an injected service:

protected override async Task OnInitializedAsync()
{
    _fooRepository.SomethingChanged += OnSomethingChanged;
    await Refresh();
}

public void Dispose()
{
    _fooRepository.SomethingChanged -= OnSomethingChanged;
}

private async Task Refresh()
{
    this.FooData = await LoadDataFromRepository();
}

Unfortunately, according to the documentation, the OnInitializedAsync method may be called twice, depending on the render mode.

I found some examples that recommend using OnAfterRenderAsync for the initialization logic instead:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        _fooRepository.SomethingChanged += OnSomethingChanged;
        await Refresh();
    }
}

[... Dispose and Refresh as above... ]

Are there disadvantages when using OnAfterRenderAsync instead of OnInitializedAsync? It seems to me that I should abandon OnInitializedAsync and default to OnAfterRenderAsync instead.

1 Answers

It's important to understand what's going on with pre-rendering.

The page is rendered twice:

  1. Once by the server to build a static version of the page. This loads and then disposes of all the components correctly.
  2. A second time by the Blazor Hub session when a SignalR session is established by blazor.server.js running in the browser session.

Points:

  1. These two loads are totally separate, and there's no leaks with registering/unregistering event handlers.
  2. This only happens when the application first loads. After than it's one load per page.
  3. OnInitialized{Async} seems the natural place for registering the event handlers, but I can't think of a compelling reason not to put them in OnAfterRender{Async}, other than you have to remember to only do it on first render. It just doesn't seem right!

If you're worried about load time with rendering a page twice, keep the landing page short and sweet.

A final comment. In your code, do the initial load of your data and then register for the SomethingChanged event.

Related