Reputation: 32966
I am upgrading my app from Blazor Ver 6/7 Server side to Ver 8 InteractiveServer. I want pre-rendering which will render the page scaffold/skeleton first, then we take the time to read from the DB to populate the page with data.
Program.cs:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
// other stuff
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
And in App.razor:
<HeadOutlet @rendermode="InteractiveServer" />
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<script src="_framework/blazor.web.js"></script>
</body>
So here's my question. In my testing OnInitializedAsync()
is called exactly once. After the scaffold/skeleton is rendered. If I put a Task.Delay()
in OnInitializedAsync()
then it goes:
This is all great. But there were issues around OnInitializedAsync()
being called twice. Is being called twice only for SSR + Streaming? And as such, not an issue here?
And... I went back and looked at an old question of mine. In one of the early release candidates for Ver 8, for InteractiveServer
mode, was it calling OnInitializedAsync()
twice?
Upvotes: 0
Views: 566
Reputation: 30177
All correct except:
You're falling back into thinking of OnAfterRenderAsync
as part of the lifecycle methods, rather than a UI Event.
This is a serious oversimplification, but consider the Blazor Synchronisation Context has two queues.
The synchronisation context prioritises the post queue over the UI event queue, which dictates when OnAfterRenderAsync
runs.
If the post queue is clear [all work queued has completed] when the renderer queues a UI event, it's run immediately. However, if the post queue is busy and the continuation from Task.Delay
is already posted [or posted while the queue is busy], OnAfterRenderAsync
is not run until the post queue clears i.e. last.
Also note that if OnInitializedAsync
yields, the component is rendered twice, and thus OnAfterRenderAsync
will be run twice.
Upvotes: 0