简体   繁体   English

JQuery数据表和.NET WebAPI性能注意事项

[英]JQuery Datatables and .NET WebAPI Performance Considerations

I just wanted to get some community input regarding a observation that i made whilst working on a Project that made use of JQuery data-tables to present data that would pull data from a setup Web API project. 我只是想从社区中获得一些意见,这是我在一个项目中进行的观察,该项目使用JQuery数据表来呈现将从设置Web API项目中提取数据的数据。

So, considering a price of code on the Web API controller that would return a list of users (GetAllUsers) - using the repository pattern: 因此,考虑使用存储库模式,Web API控制器上将返回用户列表(GetAllUsers)的代码价格:

public List<SampleUser> GetAllUsers()
{
  return Uow.SampleUser.GetAll().toList();
}

would return a list of users that could range from a number of records such as 10 to 10000. 将返回一个用户列表,该列表的范围可能是从10条到10000条这样的记录。

However, from an observation we would consume on the front end and process the data returned as such. 但是,从观察结果来看,我们将在前端进行消费并按原样处理返回的数据。 Meaning that tasks such as Paging, Searching, Filtering and Sorting are handled on the client using the for mentioned Plugin (JQuery datatable). 这意味着使用上述插件(JQuery数据表)在客户端上处理诸如分页,搜索,过滤和排序之类的任务。

Irrespective of entry point of data onto the client, whether it be Via an Ajax call or to an MVC Controller, essentially the data send to the client would be the entire set of records (of which could range to hundreds and thousands) on every load of a particular page that may request it. 无论数据是通过Ajax调用还是通过MVC Controller进入客户端的数据入口点,从本质上讲,发送给客户端的数据将是每次加载时的整个记录​​集(其范围可能成百上千)可能会请求它的特定页面。

Looking at the setup and initialization of JQuery datatables is to the point and rather straight forward: 看一下JQuery数据表的设置和初始化是很直接的一点:

$(document).ready(function () {
        var table = $('#reportTable').DataTable({
            responsive: true,
            "bServerSide": false,
            "sAjaxSource": "GetRefugeeApplicant",
            "processing": false,
            "bFilter": true,
            "sDom": "lrtip"
        });

As such, paging tasks, filtering, sorting and searching become rather easy to consider. 因此,分页任务,过滤,排序和搜索变得相当容易考虑。 However, the issue arises in the performance on the Initial Page load, being as the table of data grows so to will the number of records being pulled down. 但是,随着数据表的增长,初始页加载的性能会出现问题,被拉下的记录数也会随之增加。 To clarify, if there exists 1000 records of users then all 1000 users would be pulled down to the client end and result in more overhead on the initial call, as such tasks like paging, searching and filtering do not make calls to the server and work with what data that has been pulled down on the initial request. 要澄清的是,如果存在1000个用户记录,则所有1000个用户都将被下拉到客户端,并导致初始调用产生更多开销,因为诸如分页,搜索和筛选之类的任务不会调用服务器并正常工作初始请求中已下拉的数据。

So the question that arises here becomes one that enquirers about whether or not it would be feasible or not to load up all data to the client and work client side with said data, or alternatively have calls to the API that would handing paging tasks server side an essentially pull down a fixed number of records - say 10 - to the client. 因此,这里出现的问题变成了一个问题,即询问是否将所有数据加载到客户端并使用该数据工作客户端是否可行,或者选择调用将处理分页任务服务器端的API本质上是将固定数量的记录(例如10条)拉给客户端。 Like Such: 像这样:

public IHttpActionResult GetAllPersons(Guid id, int page = 0, int pageSize = 0, string searchQuery = "", string orderBy = "")
        {
            var response = ResponseMessage(new HttpResponseMessage(HttpStatusCode.InternalServerError));
            var personList = new Person(Uow).GetAllPersons(searchQuery);
            if (personList == null) return response;
            var totalCount = personList.Count;
            var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);

            switch (orderBy)
            {
                default:
                    personList = personList.OrderBy(c => c.PersonId).ToList();
                    break;
            }

            personList = personList
                .Skip(pageSize * page)
                .Take(pageSize)
                .ToList();

            var result = new
            {
                personList,
                pagingDetails = new
                {
                    totalPages,
                    totalCount,
                    prevLink = "",
                    nextLink = "",
                    currentCount = personList.Count
                }
            };

            var responseMessage = Request.CreateResponse(HttpStatusCode.OK, new JsonResponseObject
            {
                Data = result,
                Message = "Person Details Retrieved Successfully.",
                IsSuccessful = true
            });

            response = ResponseMessage(responseMessage);
            return response;
        }

However this approach (1) would not work correctly with JQuery Datatables due to the face it would be only returning the number of rows required and not all rows that is usually would need to work "in-memory" with. 但是,这种方法(1)不能正确地与JQuery Datatables一起使用,因为它只会返回所需的行数,而不是通常需要“内存中”处理的所有行。 (2) using this Approach would mean that on every paging call depending on the client you would have to hit the server to perform querying tasks. (2)使用这种方法意味着在每次寻呼呼叫时,根据客户端的不同,您将必须打服务器才能执行查询任务。

So i'm a bit divided in my head here, as to which would be the best solution, and if I had to with using JQuery Datatables on the client side is there any other performance considerations to look at other than those that i spoke about. 因此,我在这里有些分歧,这是最好的解决方案,如果我不得不在客户端使用JQuery Datatables,除了我刚才谈到的那些性能指标之外,还有其他性能方面的考虑要考虑。

Thanks 谢谢

You don't want to be pulling more data to your client than you have a reasonable expectation of using in a given session. 您不希望超出给定会话中使用的合理预期,而无法向客户端拉取更多数据。

This situation is what things like OData is designed to address. 这种情况正是OData旨在解决的。 It provides a standardised way of handling things like sorting, paging and filtering data between a client and an API. 它提供了一种标准化的方式来处理诸如客户端和API之间的数据排序,分页和过滤之类的事情。

Web.API has support for OData, as do a number of JavaScript components. Web.API和许多JavaScript组件都支持 OData。

Definitely recommend implementing server side paging and filtering. 绝对建议实现服务器端分页和过滤。 I'm using Datatables over WebApi exactly like this and it's working great with good performance. 我正像这样在WebApi上使用Datatables,它工作良好且性能良好。

However, a point of caution in your example: the way you implemented the GetAllPersons endpoint, it will read ALL records from the database in memory: 但是,在您的示例中要注意一点:实现GetAllPersons端点的方式,它将从内存中的数据库读取所有记录:

var personList = new Person(Uow).GetAllPersons(searchQuery);

Then it will apply paging: 然后它将应用分页:

personList = personList
                .Skip(pageSize * page)
                .Take(pageSize)
                .ToList();

This will be somewhat faster because you're not sending all data to the client, but you should apply the paging to the query so you read only the current page from the db, and request the total number of records as Count. 这将更快一些,因为您没有将所有数据发送到客户端,但是您应该将分页应用于查询,以便您仅从db中读取当前页面,并请求记录总数为Count。 This can be done in a stored procedure that returns a table and a scalar value, but it is somewhat more complicated to map this with EF and not a "pure" repository pattern. 这可以在存储过程中完成,该存储过程返回一个表和一个标量值,但是使用EF而不是“纯”存储库模式来映射它会有些复杂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM