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">