- [트러블슈팅] 랜덤 Pagination 너무 쉽게 봤다.2025년 01월 09일 23시 44분 38초에 업로드 된 글입니다.작성자: do_hyuk
처음 페이지로 회원을 나눌 때 회원을 전체 조회 후 Shuffle을 한 뒤에 해당 리스트를 페이징하는 방법을 생각했었다.
하지만 페이지네이션 특성 상 api를 호출할 때마다 다음 페이지를 요청해야하는데 이때 기준이 되는 회원 리스트는 DB에 저장되어 있는데 회원 테이블을 기준으로 하게 된다.
그렇기 때문에 기존에 생각했던 방식은 회원 전체 조회 후 랜덤하게 섞은 리스트를 계속 유지시켜야지만 구현이 가능한 것이다.
이 방식은 회원이 많아지면 많아질 수록 api를 호출할 때마다 부담이 된다고 판단하여 다른 방안을 찾아봤다.
대책 1. 페이지 마다 랜덤하게 섞기
public List<UserProfileResponseDto> getUserProfilePage(Pageable pageable){ Slice<UserInfo> users = userService.findPageBy(pageable); List<UserProfileResponseDto> responseDtoList = users.stream() .map(user -> toUserProfileResponseDto(user,Collections.emptySet())) .collect(Collectors.toList()); Collections.shuffle(responseDtoList); return responseDtoList; }
위의 코드는 회원 전체 리스트를 페이지 별로 나눈 뒤 페이지를 랜덤하게 섞는 코드이다.
해당 코드의 문제점은 새로고침을 해도 페이지별 데이터는 같다는 것이다. 단지 페이지 마다의 데이터 순서가 달라질 뿐...
대책 2. 페이지 요청 때 마다 회원 전체 조회 후 랜덤하게 뿌려주기
public List<UserProfileResponseDto> getUserProfilePage(Pageable pageable) { { // 전체 사용자 정보를 가져옵니다. List<UserInfo> allUsers = userService.findAll(); // 사용자 리스트를 셔플합니다. Collections.shuffle(allUsers); // 셔플된 리스트에서 페이징 처리합니다. int totalUsers = allUsers.size(); int start = (int) pageable.getOffset(); int end = Math.min(start + pageable.getPageSize(), totalUsers); // 페이징된 사용자 리스트를 가져옵니다. List<UserInfo> pagedUsers = allUsers.subList(start, end); return pagedUsers.stream() .map(user -> toUserProfileResponseDto(user, Colletions.emtpySet())) .collect(Collectors.toList()); }
해당 코드를 통해 요청이 들어올때마다 전체 리스트를 조회 후 섞은 뒤 리스트를 쪼개서 보내주는 코드를 생각해봤지만 사실성 요청 전 0페이지와 요청 후 1페이지의 값이 같을 수 있기 때문에 봤던 데이터를 또 볼 수도 있는 것이다. 또한 요청마다 전체 조회는 성능 저하를 일으킬 수 있기에 적용하지 못한다 판단하였다.
결론
public List<UserProfileResponseDto> getUserProfilePage(Pageable pageable){ Slice<UserInfo> users = userService.findPageBy(pageable); List<UserProfileResponseDto> responseDtoList = users.stream() .map(user -> toUserProfileResponseDto(user,Collections.emptySet())) .collect(Collectors.toList()); Collections.shuffle(responseDtoList); return responseDtoList; }
결론은 기존 코드를 사용하며 프론트 쪽에서 랜덤을 표현하기로 했다.
서버에서는 페이지 별로 랜덤하게 섞어서 보내주고, 프론트에서는 중복없이 랜덤한 페이지 번호를 요청하도록 구현했다.
'포트폴리오 > Eighteen' 카테고리의 다른 글
[트러블 슈팅] 갑자기 사라진 Redis (0) 2025.02.03 뱃지 시스템 적용 (0) 2025.01.15 [트러블 슈팅] 회원 상세 조회 문제 발생(2025.01.06) (0) 2025.01.07 [트러블 슈팅] redis 관련 문제 발생(2025.01.03) (0) 2025.01.03 [트러블 슈팅] 요청 값 Dto에 어떻게 매핑되는가 (0) 2024.11.15 댓글