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
相关产品推荐
相关产品推荐

