2016-04-01 19 views
2

JQueryデータテーブルを使用してセットアップWeb APIからデータを取得するためのデータを表示するプロジェクトで作業している間に行った観測に関するコミュニティ入力を取得したかっただけですプロジェクト。JQuery Datatablesと.NET WebAPIのパフォーマンスに関する考慮事項

ので、ユーザー(GetAllUsers)のリストを返すウェブAPIコントローラ上のコードの価格を考慮 - リポジトリパターン使用:

から及ぶ可能性があり、ユーザーのリストを返しますがレコードの数は10から10000です。

しかし、観測から私たちはフロントエンドで消費し、返されたデータを処理します。ページング、検索、フィルタリング、ソートなどのタスクが、前述のプラグイン(JQueryデータテーブル)を使用してクライアント上で処理されることを意味します。

Ajax呼び出しであってもMVCコントローラであっても、基本的にクライアントに送信されるデータは、レコードのセット全体(数百から数千に及ぶ可能性があります)に、クライアントへのデータのエントリポイントに関係なく、 )を要求する可能性のある特定のページのすべての負荷に適用されます。

はJQueryのDataTableのセットアップと初期設定を見ると、前方ではなくストレートポイントにあると:な、ページングタスク、フィルタリングなどの

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

、ソートと考えることが比較的容易になって検索しています。しかし、この問題は、データのテーブルが増えてレコードの数が引き下げられるようになっているため、初期ページの読み込み時のパフォーマンスに問題が発生します。明確にするために、1000人のユーザーレコードが存在する場合、ページング、検索、フィルタリングなどのタスクはサーバーと作業を呼び出さないため、1000人のユーザー全員がクライアント側にプルダウンされ、最初の呼び出しでオーバーヘッドが増加します最初のリクエストでどのデータがプルダウンされているかを示します。

ここで生じる問題は、すべてのデータをクライアントにロードしてクライアント側で前記データを使用することが可能かどうかを尋ねるものになります。代わりに、ハンドリングするAPIを呼び出すこともできますページングタスクのサーバー側は、本質的に固定数のレコード、例えば10をクライアントにプルダウンする。このような同様:

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; 
     } 

しかし、このアプローチは、(1)により、それだけで通常の」作業する必要がありますされて必要な行ではなく、すべての行数を返すことになる顔にjQueryのDataTableのでは正しく動作しません - メモリ "と。 (2)このアプローチを使用すると、クライアントに依存するすべてのページング呼び出しで、照会タスクを実行するためにサーバーにヒットする必要があることを意味します。

私はここで私の頭の中で一番良い解決策に分かれています。クライアント側でJQuery Datatablesを使用しなければならない場合は、他にもパフォーマンスに関する考慮事項があります私が話したこと。

おかげ

答えて

0

あなたが特定のセッションで使用しての合理的な期待を持っているよりも、あなたのクライアントに、より多くのデータを引っ張ってしたくありません。

この状況は、ODataのようなものです。これは、クライアントとAPIの間でソート、ページング、フィルタリングなどの処理を行う標準的な方法を提供します。

Web。APIには、ODataの場合はsupport、JavaScriptコンポーネントの数はいくつかあります。

0

は間違いなくサーバー側のページングやフィルタリングを実装するお勧めします。私はこのようにWebApi上でDatatablesを使用しており、優れたパフォーマンスでうまく動作しています。

しかし、あなたの例で注意する点:あなたはGetAllPersonsエンドポイント実装方法、それはメモリ内のデータベースからすべてのレコードを読み込みます:

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

そして、それはページングを適用します。

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

あなたがクライアントにすべてのデータを送信していないが、あなたはDBから現在のページのみを読むように、あなたは、クエリへのページングを適用しなければならない、とカウントとしてレコードの合計数を要求するので、これは多少速くなります。これは、テーブルとスカラー値を返すストアドプロシージャで行うことができますが、これを「純粋な」リポジトリパターンではなくEFでマッピングする方がやや複雑です。

関連する問題