Display a page loading bar progress before page is loaded

Viewed 451

Recently in Blazor I discovered that using a RenderMode of ServerPrerendered in conjunction with calling initial data in OnInitializedAsync causes OnInitializedAsync to be called twice. This causes a brief UI flash, and if I'm not pulling data from cache and straight from the database, a extra db call is made, no bueno. So I switched to using OnAfterRenderAsync and calling only when firstRender is true. This takes care of the extra call and doesn't have a UI flash, it feels nicer. However there is brief moment where not the entire page has rendered, and I'm waiting for it to load. What I would like to implement is a loading bar at the top of the page to indicate load progress, similar to what YouTube does.

I was wondering which life cycle events from the moment a hyper link is clicked to the page being rendered I need to use to make this happen? I am also assuming that I will need to use a Singleton AppState to track the load progress based on some current value over a total value to generate the bar completion progress percent.

I think I know what do do and I'm starting to try it, but I was wondering what other solutions you guys have come up with in Blazor? Any tips or suggestions?

1 Answers

I just use the OnInitializedAsync life-cycle method so long as you are calling the data using an async method like the following:

    protected override async Task OnInitializedAsync()
    {
        try
        {
            Employees = (await EmployeeDataService
        .GetAllEmployees(JobCategory?.JobCategoryId))
        .ToList();
            if (JobCategory != null)
            {
                Title = $"{JobCategory.JobCategoryName} Employees";
            }
        }
        catch (Exception e)
        {
            _loadFailed = true;
            ExceptionMessage = e.Message;
        }
    }

Then in the razor I would have various checks and display a loader as appropriate if the data has not already loaded:

    @if (Employees == null && _loadFailed == true)
    {
        <h1 class="text-danger">
          The data failed to load please try again in a little while..
        </h1>
        <h6>@ExceptionMessage</h6>
    }
    else if (Employees== null)
    {
    <div style="display:normal;margin:auto" class="loader"></div>
    }
    else if (Employees.Count==0)
    {
    <p>No employees match the criteria with a job category of 
       @JobCategory.JobCategoryName.</p>
    }
    else...

The CSS for the loader needs to exist in the site.CSS:

    .loader {
        border: 16px solid #f3f3f3;
        border-radius: 50%;
        border-top: 16px solid #3498db;
        width: 120px;
        height: 120px;
        -webkit-animation: spin 2s linear infinite; /* Safari */
        animation: spin 2s linear infinite;
    }
Related