blazorblazor-server-side

Why is OnInitializedAsync() called twice on a page reload


Normally when a page is being created & rendered in Blazor version 8, RenderMode.InteractiveServer, OnInitializedAsync() is called once. But when I do a Reload on Chrome, it is called twice. And all child components in the page are called twice too.

Why is it being called twice? And what can I do to avoid reading from the database to populate the page twice? And very importantly, in a way that will call from the database at least once for any situation?

Every time I think I finally understand the rendering mode, I realize I have it wrong again. So InteractiveServer may call OnInitializedAsync() twice if pre-rendering is on. And I want that lightening fast initial render. And there is no way to know if a call is the pre-render or post-render call. Or possibly the only-render call.

To handle this I have seen three main approaches suggested:

  1. Save the DB query to populate the page in a cache. Have the cache timeout in 15 seconds so it's basically only good for the pre (read from the DB) and post (read from the cache). That works. But, that means the pre-render call to OnInitializedAsync() may not return for several seconds. Is that ok?
  2. Only do fast operations in OnInitializedAsync(), pre & post. Then read the DB and populate the page in OnAfterRenderAsync(true). But this means initializing as part of the rendering process. And then forcing a re-render of the page. Possibly multiple re-renders as I populate multiple components in a page. Is this ok?
  3. Use [CascadingParameter] HttpContext? == null to determine if it's the pre-render.
  4. Or is there another approach?

Solution

  • Microsoft does answer this question - Persist prerendered state. So the suggested approach from Microsoft is read from the DB on the pre-render OnInitializedAsync, save that, and then reuse it for the subsequent OnInitializedAsync call.

    With that said, the solutions listed here by MrC, Logarr, and Rena are all valid approaches that work.