Sliceを使用した無限スクロールによるページ区切りのパフォーマンスの向上 パーマリンク to "Sliceを使用した無限スクロールによるページ区切りのパフォーマンスの向上"

このTipは@nkolosnjajiにより提出されました

無限スクロールのページ区切りでは、Spring Data Pageを使用してデータベースからエンティティを取得します。 これにより、2つのクエリーがトリガーされます。1つはエンティティをフェッチするためのクエリーで、2つ目はページングするアイテムの合計を決定するためのcount allクエリーです。無限スクロールには合計サイズに関する情報は必要ありませんが、ロードする次のページがある場合にのみ必要です。大規模なデータセットで作業する場合にコストのかかるcount allクエリーを回避するには、無限スクロールのパフォーマンスを向上させるPageの代わりにSliceを使用します。

フロントエンドの無限スクロールプラグインに情報を送信するために、カスタムHTTPヘッダX-Has-Next-Pageを使用します。

  • エンティティリポジトリに新しいメソッドを定義します。
Slice<YourEntity> findSliceBy(Pageable pageable);
  • web/rest/utilパッケージにあるPaginationUtil.javaに新しい静的メソッドを定義します。
public static HttpHeaders generateSliceHttpHeaders(Slice<?> slice) {
  HttpHeaders headers = new HttpHeaders();
  headers.add("X-Has-Next-Page", "" + slice.hasNext());
  return headers;
}
  • RESTコントローラーを変更して、Pageの代わりにSliceを呼び出し、新しいHTTPヘッダーを生成するようにします。
@GetMapping("/<YourEntities>")
@Timed
public ResponseEntity<List<Repo>> getAllRepos(Pageable pageable)
    throws URISyntaxException {
    Slice<YourEntity> slice = repoRepository.findSliceBy(pageable);
    HttpHeaders headers = PaginationUtil.generateSliceHttpHeaders(slice);
    return new ResponseEntity<>(slice.getContent(), headers, HttpStatus.OK);
}
  • 新しいビューモデルをentity.controller.jsで定義します。
vm.hasNextPage = false;
  • 応答からHTTPヘッダー値を抽出し、それをビューモデルに割り当てます。
function onSuccess(data, headers) {
    vm.hasNextPage = headers('X-Has-Next-Page') === "true";
    ...
}
  • <your-entities>.htmlで無限スクロールプラグインを使ったビューモデルを使用します。
<tbody infinite-scroll="vm.loadPage(vm.page + 1)" infinite-scroll-disabled="!vm.hasNextPage">