Día de Ruru
20230413 TIL 본문
문제점
무한스크롤을 위해서 페이지네이션을 해야한다. 그런데 response 해주는 배열 자체가 여러개의 테이블에서 얻은 배열을 하나로 합친거여서 repository 계층에서 limit 과 offset을 사용할 수 가 없었다. 조회된 배열을 원하는 페이지만큼 잘라서 보내주는 방식으로 페이지네이션을 구현할 수 있을까..?
해결방법
자바스크립트의 slice()함수를 사용하면 간단하게 페이지네이션을 구현할 수 있을 것 같다!! 일단 query로 값을 받아와야 한다. 아래처럼 req.query 로 값을 받은 후, 숫자 형식으로 변환해주어야 한다. (쿼리는 항상 문자열)
const pageInfo = req.query;
const pageNum = parseInt(pageInfo.pageNum);
const pageSize = parseInt(pageInfo.pageSize);
이후 해당 배열에 slice 로 사용해주면 된다.
배열을 자르는 시작점은 1일때 0번부터 시작하고 2일때는 pageNum 만큼 넘긴 숫자부터 시작해야 한다. 3일때는 pageNum을 두번 한 만큼의 숫자부터 시작해야한다. 그러므로 pageSize * (pageNum - 1)에서 시작한다.
배열을 자르는 개수는 pageNum 이 1이고 pageSize가 5일 때 5 만큼 잘라야하고 pageNum 이 2면 10만큼 잘라야한다. 그러므로 pageSize * pageNum 만큼 자른다.
const meetings = meeting.slice(pageSize * (pageNum - 1), pageSize * pageNum);
✔ 고민해봐야할 점
하지만 이 경우 성능상의 문제가 발생한다. 내가 기존에 작성한 코드는 아래와 같이 각 테이블에서 조건에 맞는 데이터들을 배열로 받은 후 하나의 배열로 합치고 정렬을 해준다.
//service 계층 코드
getMyfile = async ({ userId }) => {
const meeting = await this.MypageRepository.findMyMeetingfile({
userId,
});
const report = await this.MypageRepository.findMyReportfile({ userId });
console.log(meeting,report)
let result = [];
return result.concat(meeting, report).sort((a, b) => b.Id - a.Id);
};
//controller 계층 코드
const myfile = await this.MypageService.getMyfile({ userId });
const myfiles = myfile.slice(
pageSize * (pageNum - 1),
pageSize * pageNum
);
res.status(200).json({ myfiles });
만약 내가 원하는 데이터가 pageNum은 1이고 pageSize가 10일 때 딱 열개의 데이터만 가져올 수 있어야 하는데 이미 모든 데이터를 다 받아온 후 잘라서 데이터를 보내주게 된다. 이게 페이지를 스크롤하지 않을 때에는 크게 문제가 되지 않을 수 있지만 스크롤을 계속 내리면서 같은 API를 계속 호출하게 되면 나는 2번 페이지 3번 페이지의 값을 보내줄 때 마다 계속 전체 데이터를 조회 한 후 잘라서 보내줘야 한다.
이 부분이 서버의 성능에 영향을 끼치는 것 같다. 해결하기 위해서는 코드와 테이블의 관계성을 다시 수정하는 방법과 캐시를 사용하는 방법이 있을 것 같다. 나중에 시간이 좀 생기면 캐시로 해결할 수 있는 방법이 있을지 공부해보아야 할 것 같다.
'항해99 > TIL' 카테고리의 다른 글
20230418 TIL (1) | 2023.04.19 |
---|---|
20230414 TIL (0) | 2023.04.15 |
20230411 TIL (0) | 2023.04.12 |
20230410 TIL (0) | 2023.04.11 |
20230406 TIL (0) | 2023.04.07 |