Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions aspnetcore/blazor/components/rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,10 @@ For approaches to manage state, see the following resources:
For the state manager approach, C# events are outside the Blazor rendering pipeline. Call <xref:Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged%2A> on other components you wish to rerender in response to the state manager's events.

The state manager approach is similar to the earlier case with <xref:System.Timers.Timer?displayProperty=fullName> in the [previous section](#receiving-a-call-from-something-external-to-the-blazor-rendering-and-event-handling-system). Since the execution call stack typically remains on the renderer's synchronization context, calling <xref:Microsoft.AspNetCore.Components.ComponentBase.InvokeAsync%2A> isn't normally required. Calling <xref:Microsoft.AspNetCore.Components.ComponentBase.InvokeAsync%2A> is only required if the logic escapes the synchronization context, such as calling <xref:System.Threading.Tasks.Task.ContinueWith%2A> on a <xref:System.Threading.Tasks.Task> or awaiting a <xref:System.Threading.Tasks.Task> with [`ConfigureAwait(false)`](xref:System.Threading.Tasks.Task.ConfigureAwait%2A). For more information, see the [Receiving a call from something external to the Blazor rendering and event handling system](#receiving-a-call-from-something-external-to-the-blazor-rendering-and-event-handling-system) section.

## WebAssembly loading progress indicator for Blazor Web Apps

<!-- UPDATE 9.0 Will be removed for a new feature in this area.
Tracked by: https://github.com/dotnet/aspnetcore/issues/49056 -->

A loading progress indicator isn't present in an app created from the Blazor Web App project template. A new loading progress indicator feature is planned for a future release of .NET. In the meantime, an app can adopt custom code to create a loading progress indicator. For more information, see <xref:blazor/fundamentals/startup#client-side-loading-progress-indicators>.
123 changes: 122 additions & 1 deletion aspnetcore/blazor/fundamentals/startup.md
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,128 @@ For more information on CSPs, see <xref:blazor/security/content-security-policy>

## Client-side loading progress indicators

*This section only applies to Blazor WebAssembly apps.*
A loading progress indicator shows the loading progress of the app to users, indicating that the app is loading normally and that the user should wait until loading is finished.

:::moniker-end

:::moniker range=">= aspnetcore-8.0"

### Blazor Web App loading progress

The loading progress indicator used in Blazor WebAssembly apps isn't present in an app created from the Blazor Web App project template. Usually, a loading progress indicator isn't desirable for interactive WebAssembly components because Blazor Web Apps prerender client-side components on the server for fast initial load times. For mixed-render-mode situations, the framework or developer code must also be careful to avoid the following problems:

* Showing multiple loading indicators on the same rendered page.
* Inadvertently discarding prerendered content while the WebAssembly runtime is loading.

<!-- UPDATE 9.0 Will be removed for a new feature in this area.
Tracked by: https://github.com/dotnet/aspnetcore/issues/49056 -->

A future release of .NET might provide a framework-based loading progress indicator. In the meantime, you can add a custom loading progress indicator to a Blazor Web App.

Create a `LoadingProgress` component in the `.Client` app that calls <xref:System.OperatingSystem.IsBrowser%2A?displayProperty=nameWithType>:

* When `false`, display a loading progress indicator while the Blazor bundle is downloaded and before the Blazor runtime activates on the client.
* When `true`, render the requested component's content.

The following demonstration uses the loading progress indicator found in apps created from the Blazor WebAssembly template, including a modification of the styles that the template provides. The styles are loaded into the app's `<head>` content by the <xref:Microsoft.AspNetCore.Components.Web.HeadContent> component. For more information, see <xref:blazor/components/control-head-content>.

`LoadingProgress.razor`:

```razor
@if (!OperatingSystem.IsBrowser())
{
<HeadContent>
<style>
.loading-progress {
position: relative;
display: block;
width: 8rem;
height: 8rem;
margin: 20vh auto 1rem auto;
}

.loading-progress circle {
fill: none;
stroke: #e0e0e0;
stroke-width: 0.6rem;
transform-origin: 50% 50%;
transform: rotate(-90deg);
}

.loading-progress circle:last-child {
stroke: #1b6ec2;
stroke-dasharray:
calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8),
500%;
transition: stroke-dasharray 0.05s ease-in-out;
}

.loading-progress-text {
position: relative;
text-align: center;
font-weight: bold;
top: -90px;
}

.loading-progress-text:after {
content: var(--blazor-load-percentage-text, "Loading");
}

code {
color: #c02d76;
}
</style>
</HeadContent>
<svg class="loading-progress">
<circle r="40%" cx="50%" cy="50%" />
<circle r="40%" cx="50%" cy="50%" />
</svg>
<div class="loading-progress-text"></div>
}
else
{
@ChildContent
}

@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
```

In a component that adopts Interactive WebAssembly rendering, wrap the component's Razor markup with the `LoadingProgress` component. The following example demonstrates the approach with the `Counter` component of an app created from the Blazor Web App project template.

`Pages/Counter.razor`:

```razor
@page "/counter"
@rendermode InteractiveWebAssembly

<PageTitle>Counter</PageTitle>

<LoadingProgress>
<h1>Counter</h1>

<p role="status">Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</LoadingProgress>

@code {
private int currentCount = 0;

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

### Blazor WebAssembly app loading progress

:::moniker-end

:::moniker range=">= aspnetcore-7.0"

The project template contains Scalable Vector Graphics (SVG) and text indicators that show the loading progress of the app.

Expand Down