You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor应用优化:如何实现先加载页面再从数据库填充数据?

解决Blazor页面先加载框架再异步填充数据的问题

嘿,我完全懂你的担忧——同步加载数据会直接阻塞页面渲染,现在小数据集都要1-2秒,数据量上去了肯定更糟。咱们要实现的就是先渲染页面框架,后台异步拉取数据填充的效果,其实只要把同步数据操作改成异步非阻塞模式就行,我一步步给你讲怎么改:

第一步:把数据仓储改成异步模式

你的IRepository和Repository目前都是同步方法,这会导致组件初始化时一直等着数据返回,没法先渲染页面。咱们先把它改成异步版本:

修改IRepository接口

注意using语句要放在命名空间外面,接口方法改成异步返回Task<List<Employee>>(符合C#异步命名规范,后缀加Async):

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace BlazorCompanyManager.Data
{
    public interface IRepository
    {
        Task<List<Employee>> GetEmployeesAsync();
        Task<Employee> GetEmployeeAsync(Guid id);
        Task<bool> UpdateEmployeeAsync(Employee employee);
        Task AddEmployeeAsync(Employee employee);
        Task DeleteEmployeeAsync(Guid id);
    }
}

修改Repository实现类

利用EF Core的异步扩展方法(需要引用Microsoft.EntityFrameworkCore),把同步的ToList()改成异步的ToListAsync():

using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace BlazorCompanyManager.Data
{
    public class Repository : IRepository
    {
        protected readonly ApplicationDbContext dbContext;

        public Repository(ApplicationDbContext db)
        {
            this.dbContext = db;
        }

        public async Task<List<Employee>> GetEmployeesAsync()
        {
            // 异步查询,不会阻塞主线程
            return await this.dbContext.EmployeeTable.ToListAsync();
        }

        // 其他方法同理改成异步,比如GetEmployeeAsync:
        public async Task<Employee> GetEmployeeAsync(Guid id)
        {
            return await this.dbContext.EmployeeTable.FirstOrDefaultAsync(e => e.Id == id);
        }

        // Update、Add、Delete方法也按异步模式修改,这里就不一一列举了
    }
}

第二步:修改Blazor组件实现异步初始化

现在组件可以用OnInitializedAsync异步加载数据,同时初始化空列表和加载状态,让页面先渲染框架:

public class EmployeesBase : ComponentBase
{
    [Inject]
    protected IRepository Repository { get; set; }
    // 先初始化空列表,避免渲染时出现null引用
    protected List<BlazorCompanyManager.Data.Employee> employees = new();
    // 增加加载状态,用来显示加载提示
    protected bool isLoading = true;

    protected override async Task OnInitializedAsync()
    {
        // 异步获取数据,不会阻塞页面渲染
        employees = await Repository.GetEmployeesAsync();
        // 数据加载完成后更新状态
        isLoading = false;
        // 不需要手动调用StateHasChanged,Blazor会自动处理状态变更触发重新渲染
    }
}

第三步:在Razor页面添加加载状态UI

最后在你的员工列表Razor文件里,先渲染页面框架(比如表格表头),加载时显示提示,数据到位后再展示内容:

<h3>员工列表</h3>

@if (isLoading)
{
    <p>正在加载数据...</p> <!-- 先显示加载提示,让用户知道页面在工作 -->
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>姓名</th>
                <th>部门</th>
                <!-- 其他表头列 -->
            </tr>
        </thead>
        <tbody>
            @foreach (var emp in employees)
            {
                <tr>
                    <td>@emp.Name</td>
                    <td>@emp.Department</td>
                    <!-- 其他数据列 -->
                </tr>
            }
        </tbody>
    </table>
}

为什么之前用OnInitializedAsync没成功?

大概率是因为你的仓储方法还是同步的——就算用了OnInitializedAsync,里面调用同步的GetEmployees()还是会阻塞线程,页面根本没法先渲染。现在改成全异步链路后,组件初始化时会立刻返回渲染页面框架,后台悄悄拉取数据,数据加载完成后自动更新UI,完美解决你的问题!

内容的提问来源于stack exchange,提问作者10101

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 02:52:45