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

Blazor Server绑定15万条数据集致Chrome内存不足的解决建议

Blazor Server绑定15万条数据集内存溢出问题解决方案建议

我正在使用Blazor Server构建应用,测试将15万条数据集绑定到Blazor DataTable时,Chrome页面出现Out of Memory Error;测试Telerik Blazor Grid也出现相同错误,DevExpress Blazor Grid可正常显示但功能有限。我不想缩小数据集或修改Chrome内存限制,数据集由DbContext Factory和.NET6 EF生成,恳请提供绑定大数据集不内存不足的建议。


现有Telerik Grid代码

<TelerikGrid Data="@cityList"
             Height="700px" Reorderable="true"
             FilterMode="@GridFilterMode.FilterMenu"
             FilterMenuType="@FilterMenuType.CheckBoxList"
             Pageable="true"  Groupable="true"
             Sortable="true"  Resizable="true"                                       
             SelectionMode="GridSelectionMode.Multiple"
             @bind-SelectedItems="@SelectedItems"
             PageSize="100" class="table table-sm table-nowrap"
             EditMode="@GridEditMode.Inline"  ConfirmDelete="true"
             OnUpdate="@UpdateItem" OnDelete="@DeleteItem"
            >
    <GridToolBar>                                     
        <span class="k-toolbar-spacer"></span>
        <GridSearchBox  Width="300px" DebounceDelay="200">
        </GridSearchBox>
        <GridCommandButton Command="ExcelExport" Icon="file-excel">Export to Excel</GridCommandButton>
        <GridCommandButton Command="BatchDelete" OnClick="BatchDelete" Icon="comments-remove">Batch Delete</GridCommandButton>
        <label>Page Size</label>
        <select @onchange=@ChangePageSize>
            <option value="100" selected>100</option>
            <option value="250">250</option>
            <option value="500">500</option>
            <option value="1000">1000</option>
            <option value="all" >all</option>
        </select>
    </GridToolBar>
    <GridSettings>
        <GridValidationSettings Enabled="true" />
    </GridSettings>
    <GridExport>
        <GridExcelExport FileName="CityList"  AllPages="true" />
    </GridExport>

    <GridColumns>
        <GridCheckboxColumn SelectAll="true"></GridCheckboxColumn>
        <GridColumn Width="8%" Field=@nameof(BasCity.CityId) Title="ID" Editable = "false"/>
        <GridColumn Width="10%" Field=@nameof(BasCity.Name) Title="Name" />
        <GridColumn Width="20%" Field=@nameof(BasCity.StateName) Title="State Name" />
        <GridColumn Width="20%" Field=@nameof(BasCity.CountryName) Title="Country Name" />
      
    
        <GridCommandColumn Width="100px">
            <GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
            <GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
            <GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Update</GridCommandButton>
            <GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel</GridCommandButton>
        </GridCommandColumn>
    </GridColumns>
</TelerikGrid>

后端加载数据代码

protected override async Task OnInitializedAsync()
{
    try
    {
        await LoadListAsync(null);
    }
    catch(Exception ex)
    {
        await processError?.SaveError(ex, null, "CityListOnInitializedAsync");
    }
}

private async Task LoadListAsync(string? searchTerm)
{
    try
    {
        if(string.IsNullOrEmpty(searchTerm))
            cityList = await cityService?.ListAsync();
        else
            cityList = await cityService?.SearchListAsync(searchTerm);
    }
    catch(Exception ex)
    {
        await processError?.SaveError(ex, null, "CityListLoadListAsync");
    }
}

解决方案建议

1. 强制实现服务器端分页、排序、过滤

当前代码虽开启分页,但cityList是一次性加载全部15万条数据到内存,这是内存溢出的核心原因。

  • 修改ListAsync和SearchListAsync方法,接收分页参数(页码、页大小)、排序字段、过滤条件,用EF的Skip()+Take()实现服务器端分页
  • Telerik Grid支持直接绑定IQueryable<T>,将EF未枚举的查询结果绑定到Grid,Grid会自动把分页、排序、过滤参数传递到服务器,彻底避免一次性加载全量数据

2. 禁用高内存开销的客户端功能

  • 关闭FilterMenuType="CheckBoxList":该功能需要加载全量选项到客户端,15万条数据的选项列表会占用大量内存,建议改为FilterMenuType.Menu或完全依赖服务器端过滤
  • 移除SelectAll="true"全选功能:全选需要维护所有行的选中状态,内存开销极大;若必须保留,改为服务器端处理(仅记录选中ID,而非存储整个实体)

3. 使用轻量级DTO替代实体类

当前绑定的BasCity实体可能包含大量未在Grid中展示的属性,冗余数据会浪费内存和带宽:

  • 创建仅包含Grid所需字段的DTO类(如CityGridDto,仅保留CityId、Name、StateName、CountryName)
  • EF查询时通过Select()投影到DTO,减少数据传输量和内存占用

4. 开启虚拟滚动优化渲染

  • 给Telerik Grid添加ScrollMode="@GridScrollMode.Virtual",仅渲染当前视口内的行,大幅减少DOM节点数量,降低客户端内存消耗

5. 优化EF Core查询

  • 查询时添加AsNoTracking(),EF不会缓存实体,减少服务器内存占用
  • 禁用延迟加载,避免意外加载关联数据导致内存膨胀

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:57:35