gpt4 book ai didi

javascript - Kendo 网格性能问题(Kendo Grid + Angular JS + Web API)

转载 作者:行者123 更新时间:2023-11-30 20:36:37 25 4
gpt4 key购买 nike

问题:

我的 Angular JS html 页面中有 Kendo Grid。 Kendo Grid 数据来 self 的远程服务 Web API。

当我们进行分页(或第一次加载页面)时,Kendo 网格尝试在浏览器中为每 10 条记录下载 38 MB 的内容,这大约需要。 6 分钟加载数据。

它下载 38 MB 的内容和内容是什么?

我已经通过阅读/学习关于堆栈溢出的类似支持票证实现了什么:

  1. 实现了服务器分页 true(pageSize = 10,总记录数 = 56000 左右)

  2. JS和CSS的捆绑

  3. 我尝试了以下两个选项:

    可滚动:{虚拟:真实}或者可滚动:{ 无穷无尽:真 }

  4. 我在生产环境中检查了我的存储过程,它在大约 3 秒内执行完毕。 55000条记录。 (在生产和暂存两台服务器上)。

  5. 我检查了我的 Web API Controller ,它在不到 4 秒内将响应返回给 kendo 网格,然后 kendo 网格需要太多时间来填充数据。

  6. 我有以下用于 Kendo 的 JS 和 CSS(已经实现捆绑):

    • Kendo.all.min.js
    • kendo.bootstrap.min.css
    • kendo.common-bootstrap.min.css
    • 项目需要的其他JS、CSS也以捆绑方式加载。

以下是我的实时项目页面:

HTML 页面:

<div id="heatMapGrid" kendo-grid k-options="vm.heatMapGridOptions"></div>

AngularJS Controller :

var dataSourceHeatMapGrid = new kendo.data.DataSource({
transport: {
read: function (options) {

heatMapService.getHeatMapGrid(options.data, heatMapGridParams)
.then(function (response) {
options.success(response.data);
$rootScope.optioncallback = options;

//$scope.htmapGridCSV = [];
//$scope.htmapGridCSV = response.data.exportData;

}).catch(function (e) {
console.log('Error: ', e);
throw e;
});
},
parameterMap: function (options) {
return JSON.stringify(options);
}
},
schema: {
data: function (response) {
return response.gridData;
},
total: function (response) {
return response.Total;
},
model: {
fields: {
TPID: { type: "number" },
TPName: { type: "string" },
EndCustomerPurchaseAmt: { type: "number" },
PrimaryExpirationMonth: { type: "string" },
AgreementID: { type: "number" },
TotalPurchased: { type: "number" },
TotalAssigned: { type: "number" },
OverUnder: { type: "number" },
VSEntPurchasedUnits: { type: "number" },
VSProMSDNUnits: { type: "number" },
VSTestProMSDNUnits: { type: "number" },
MSDNPlat: { type: "number" },
CloudPurchasedUnits: { type: "number" },
UnbilledOverage: { type: "number" },
AzurePotentialRevenue: { type: "number" }
}
}
},
pageSize: 10,
serverPaging: true
});

vm.heatMapGridOptions = {
columns: [
{ "title": "", template: "<a title='#=TPID#' #=isPinnedAccount==1 ? \"class='terrunpinaccount'\" : \"class='terrpinaccount'\"# ng-click='vm.pinUnpinAccount(\"#=TPID#\")'></a>" },
{ "title": "Account Name", "field": "TPName", template: "<a href='javascript:void(0);' ng-click='vm.tPIDDetails(\"#=TPID#\",\"#=TPName#\")' title='#=TPName#'><div class='DisplayTitleTPName'>#=TPName#<ul><li>AM: #=AM#, OM: #=OperatingModel#, Country: #=Country#</li><li>DevSales Lead: #=SalesLead#, SSP: #=Dev_SSP#, TSP: #=DevTSP#</li></ul></div></a>", headerAttributes: { style: "white-space: normal; overflow: visible;" } },
{
"title": "PERFORMANCE AND ANNIVERSARIES", headerAttributes: { style: "text-align: center;font-weight: bold;" },
columns:
[{
"title": "Renewals and True Ups", headerAttributes: { style: "text-align: center;font-weight: bold;" },
columns: [{ "title": "Total Annualized Expiring", "field": "EndCustomerPurchaseAmt", format: "{0:c0}", headerAttributes: { style: "white-space: normal; overflow: visible;" } },
{ "title": "Primary Anniversary Month", "field": "PrimaryExpirationMonth", headerAttributes: { style: "white-space: normal; overflow: visible;" } },
{ "title": "Agreement Number", "field": "AgreementID", format: "{0:n0}", headerAttributes: { style: "white-space: normal; overflow: visible;" } }]
}]
},
{
"title": "EFFECTIVE LICENSE POSITIONS", headerAttributes: { style: "text-align: center;font-weight: bold;" },
columns:
[{
"title": "Visual Studio Subscriptions", headerAttributes: { style: "text-align: center;font-weight: bold;" },
columns: [{ "title": "Purchased", "field": "TotalPurchased", format: "{0:n0}" },
{ "title": "Assigned", "field": "TotalAssigned", format: "{0:n0}" },
{ "title": "Over Under", "field": "OverUnder", format: "{0:n0}" }]
},
{
"title": "Account Footprint (Active SA Licenses)", headerAttributes: { style: "text-align: center;font-weight: bold;" },
columns: [{ "title": "Enterprise w/ MSDN", "field": "VSEntPurchasedUnits", format: "{0:n0}", headerAttributes: { style: "white-space: normal; overflow: visible;" } },
{ "title": "Pro w/ MSDN", "field": "VSProMSDNUnits", format: "{0:n0}", headerAttributes: { style: "white-space: normal; overflow: visible;" } },
{ "title": "Test Pro w/ MSDN", "field": "VSTestProMSDNUnits", format: "{0:n0}", headerAttributes: { style: "white-space: normal; overflow: visible;" } },
{ "title": "MSDN Platforms", "field": "MSDNPlat", format: "{0:n0}", headerAttributes: { style: "white-space: normal; overflow: visible;" } },
{ "title": "Cloud", "field": "CloudPurchasedUnits", format: "{0:n0}" }]
},
{
"title": "Azure", headerAttributes: { style: "text-align: center;font-weight: bold;" },
columns: [{ "title": "Unbilled Overage", "field": "UnbilledOverage", format: "{0:c0}", headerAttributes: { style: "white-space: normal; overflow: visible;" } },
{ "title": "Potential Revenue", "field": "AzurePotentialRevenue", headerTemplate: '<span title="Potential Revue is based on the delta of activated seats and <br/> developers deploying to Azure multiplied by the annual <br/> value of an Azure attached developer ($15k)">Potential Revenue</span>', format: "{0:c0}", headerAttributes: { style: "white-space: normal; overflow: visible;" } }]
}]
}
],
groupable: false,
sortable: true,
resizable: true,
//pageable: true,
pageable: {
refresh: true,
pageSizes: [10, 20, 50],

},
columnMenu: true,
scrollable: false
//filterable: true
};

$("#heatMapGrid").data("kendoGrid").setDataSource(dataSourceHeatMapGrid);

AngularJS 服务:

services.getHeatMapGrid = function (command, heatMapGridParams) {
var data = {
page: command.page,
pageSize: command.pageSize,
skip: command.skip,
take: command.take,
alias: heatMapGridParams.alias,
hasDevTest: heatMapGridParams.hasDevTest,
hasDevTestLabs: heatMapGridParams.hasDevTestLabs,
hasXamarin: heatMapGridParams.hasXamarin,
devOpsMSShopFlag: heatMapGridParams.devOpsMSShopFlag,
devOpsOSSThirdPartyShopsFlag: heatMapGridParams.devOpsOSSThirdPartyShopsFlag,
intelligentAppsFlag: heatMapGridParams.intelligentAppsFlag,
paaSServicesFlag: heatMapGridParams.paaSServicesFlag,
enterpriseStepUpFlag: heatMapGridParams.enterpriseStepUpFlag,
devsLearningAzureFlag: heatMapGridParams.devsLearningAzureFlag,
devOpsAcceleratorEligibleFlag: heatMapGridParams.devOpsAcceleratorEligibleFlag,
overAssignedFlag: heatMapGridParams.overAssignedFlag,
lowAssignmentsFlag: heatMapGridParams.lowAssignmentsFlag,
hasCloudSubscriptionFlag: heatMapGridParams.hasCloudSubscriptionFlag,
hasUnbilledOverageFlag: heatMapGridParams.hasUnbilledOverageFlag,
hasDevTestOppty: heatMapGridParams.hasDevTestOppty,
areaID: heatMapGridParams.areaID,
countryID: heatMapGridParams.countryID,
segmentID: heatMapGridParams.segmentID,
subsegmentID: heatMapGridParams.subsegmentID,
salesUnitID: heatMapGridParams.salesUnitID,
agreementRenewalOrTrueupID: heatMapGridParams.agreementRenewalOrTrueupID,
aM: heatMapGridParams.aM,
industry: heatMapGridParams.industry,
hasAppServOppty: heatMapGridParams.hasAppServOppty,
hasDotNetDeveloperFlag: heatMapGridParams.hasDotNetDeveloperFlag,
paaSReadyFlag: heatMapGridParams.paaSReadyFlag,
startMonth: heatMapGridParams.startMonth,
endMonth: heatMapGridParams.endMonth
};
return $http({ method: 'GET', url: config.apiUrl + 'Account/HeatMapGrid/', params: data });
};

网络接口(interface):

[HttpGet]
public heatMapGridAndExport HeatMapGrid([FromUri]HeatMapGridModel model)
{
ListView listView = new ListView();

List<getHeatMapDataGlobalFilter_Result> listGridDataForTotalCount = new List<getHeatMapDataGlobalFilter_Result>();
listGridDataForTotalCount = listView.GetListViewGridData(model.alias, model.hasDevTest, model.hasDevTestLabs, model.hasXamarin, model.devOpsMSShopFlag, model.devOpsOSSThirdPartyShopsFlag, model.intelligentAppsFlag, model.paaSServicesFlag, model.enterpriseStepUpFlag, model.devsLearningAzureFlag, model.devOpsAcceleratorEligibleFlag, model.overAssignedFlag, model.lowAssignmentsFlag, model.hasCloudSubscriptionFlag, model.hasUnbilledOverageFlag, model.hasDevTestOppty, model.areaID, model.countryID, model.segmentID, model.subsegmentID, model.salesUnitID, model.agreementRenewalOrTrueupID, model.aM, model.industry, model.hasAppServOppty, model.hasDotNetDeveloperFlag, model.paaSReadyFlag, model.startMonth, model.endMonth);

List<getHeatMapDataGlobalFilter_Result> listGridData = new List<getHeatMapDataGlobalFilter_Result>();
listGridData = listGridDataForTotalCount.Skip(model.skip).Take(model.take).OrderByDescending(c => c.EndCustomerPurchaseAmt).ToList();

//List<heatMapExport> listExportData = new List<heatMapExport>();
//listExportData = listGridDataForTotalCount.Select(c => new heatMapExport()
//{
// TPName = c.TPName,
// TPID = c.TPID,
// OperatingModel = c.OperatingModel,
// Area = c.Area,
// Country = c.Country,
// CreditedRegion = c.CreditedRegion,
// CreditedDistrict = c.CreditedDistrict,
// Segment = c.Segment,
// ATUManager = c.ATUManager,
// Dev_SSP = c.Dev_SSP,
// AM = c.AM,
// Industry = c.Industry,
// ATSName = c.ATSName,
// AssignedPect = string.Format("{0:p0}", c.AssignedPect),
// ActivatedPect = string.Format("{0:p0}", c.ActivatedPect),
// AzureActivated = Convert.ToString(c.AzureActivated),
// EndCustomerPurchaseAmt = string.Format("{0:c0}", c.EndCustomerPurchaseAmt),
// PrimaryExpirationMonth = Convert.ToString(c.PrimaryExpirationMonth),
// AgreementID = Convert.ToString(c.AgreementID),
// TotalPurchased = string.Format("{0:n0}", c.TotalPurchased),
// TotalAssigned = string.Format("{0:n0}", c.TotalAssigned),
// OverUnder = string.Format("{0:n0}", c.OverUnder),
// VSEntPurchasedUnits = string.Format("{0:n0}", c.VSEntPurchasedUnits),
// VSProMSDNUnits = string.Format("{0:n0}", c.VSProMSDNUnits),
// VSTestProMSDNUnits = string.Format("{0:n0}", c.VSTestProMSDNUnits),
// MSDNPlat = string.Format("{0:n0}", c.MSDNPlat),
// CloudPurchasedUnits = string.Format("{0:n0}", c.CloudPurchasedUnits),
// UnbilledOverage = string.Format("{0:c0}", c.UnbilledOverage),
// AzurePotentialRevenue = string.Format("{0:c0}", c.AzurePotentialRevenue)
//}).ToList();
var heatMapData = new heatMapGridAndExport
{
gridData = listGridData,
//exportData = listExportData,
Total = listGridDataForTotalCount.Count()
};
return heatMapData;
}

我的环境:

  1. 版本 Telerik Control - Kendo UI v2017.2.621

  2. 操作系统开发机器 - Windows 10 Enterprise(8 GB RAM,Intel Core i7 处理器,64 位)(客户端操作系统)

  3. 浏览器 - Google Chrome,版本 65.0.3325.181

  4. .NET Framework - 版本 4.6.1

  5. Visual Studio - Enterprise 2015,版本 14.0.25431.01(更新 3)

  6. 编码语言 - C#

这是生产服务器的浏览器屏幕截图:

Here is my production server kendo grid, which takes almost 12 minutes to populate data in kendo grid, and you can see TTFB (Time To First Byte. This timing includes 1 round trip of latency and the time the server took to prepare the response) for this request is 3.26 seconds

这是我点击第 2 页时的另一个屏幕截图,它再次下载 38 MB 的内容,大约需要 2 分钟。 6分钟。 (服务器分页 = true 和 pageSize = 10)

enter image description here

代码调试截图:

enter image description here

我做错了什么?谁能帮帮我。

提前谢谢你。

最佳答案

您能否禁用将约 56K 行导出数据附加到 WebAPI 响应的行并查看它的执行情况?我怀疑这是你的问题

    var heatMapData = new heatMapGridAndExport
{
gridData = listGridData,
//exportData = listExportData, //perhaps make conditional, for export only?
Total = listGridDataForTotalCount.Count()
};
return heatMapData;

编辑:因为这似乎没有解决您的问题,您能否尝试像这样重新排序 Linq 方法调用,因为您得到的行为意味着整个结果集正在返回?

listGridData =
listGridDataForTotalCount.OrderByDescending(c => c.EndCustomerPurchaseAmt)
.Skip(model.skip).Take(model.take).ToList();

我不确定,但我想知道是否有 OrderByDescending last 强制 Linq 返回到整个结果集,这就是您最终从 ToList 得到的结果?

关于javascript - Kendo 网格性能问题(Kendo Grid + Angular JS + Web API),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49772055/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com