만약 페이지 조회 요청 순서가 1 -> 2 -> 1 이라면 총 세번 요청하게 됩니다.
하지만 만약 해당 게시판이 커뮤니티처럼 데이터가 유동적으로 계속 바뀌는 것이 아니라 역사 자료 게시판(?)처럼 변동성이 낮다면 어떨까요?
1을 받았을 때 1을 저장해뒀다가 1페이지를 다시 요청하면 이전에 받았던 정보를 다시 사용하면 되지 않을까요?
이러한 처리를 캐싱 이라고 합니다.
(알고리즘에도 많이 사용되죠!)
오늘은 캐싱 기능을 추가해보겠습니다.
캐싱이 많으면 무조건 좋을까요? 그건 아닙니다. 왜냐하면 받은 데이터를 전부 저장해버리면 언젠가 메모리 overflow가 발생하기 때문입니다. 따라서 오늘은 한계점을 지정하고 그 한계를 벗어나면 메모리에서 삭제되도록 구현하겠습니다.
테스트 추가하기
app.test.js에 테스트를 추가해줍니다.
// app.test.js
it("같은 page로 loadPosts를 2번 호출하면 fetchPosts는 한번만 불러와야 한다.", async () => {
await app.loadPosts(2);
await app.loadPosts(2);
expect(mockFetchPosts).toHaveBeenCalledTimes(1);
});
it("캐싱은 페이지 3개만 해야한다.2,3,4,5,2 순서로 호출한다면 총 5번 호출되어야 한다. ", async () => {
const pageMemoryLimit = 3;
for (let i = 2; i <= 2 + pageMemoryLimit; i++) {
await app.loadPosts(i);
}
await app.loadPosts(2);
expect(mockFetchPosts).toHaveBeenCalledTimes(5);
});
일단 테스트 통과시키기
app.js의 loadPosts를 아래처럼 수정해주고 필요한 함수를 추가합니다.
그리고 App에 필요한 변수도 추가합니다.
async loadPosts(page) {
if (!this.#pageMemory.has(page)) {
try {
const newPageData = await this.fetchPosts(page);
this.#pageMemoQueue.push(page);
this.#pageMemory.set(page, newPageData);
this.checkPageMemoryLimit();
} catch (error) {
console.error("Error loading posts:", error);
return;
}
}
this.postsData = this.#pageMemory.get(page);
this.updateUI();
}
async fetchPosts(page) {
const response = await fetch(
`${App.#API_URL}?page=${page}&limit=${this.limit}`
);
if (response.status !== 200) {
throw new Error(`Failed to fetch posts: ${response.statusText}`);
}
return await response.json();
}
checkPageMemoryLimit = () => {
if (this.#pageMemory.size > this.#pageMemoryLimit) {
const targetDeleteFromMemoryPage = this.#pageMemoQueue.splice(0, 1)[0];
this.#pageMemory.delete(targetDeleteFromMemoryPage);
}
};
그럼 아래처럼 테스트가 모두 통과합니다!
그리고 리팩토링을 해줍니다.
리팩토링 단계
테스트를 작성할 단계에서는 pageMemoryLimit라는 변수도 없었고, 변수명도 못지어서 그냥 숫자 3으로 하드코딩하였었는데, 이를 수정하겠습니다.
아래처럼 테스트의 이름도 그럴듯하게 작성해주면 끝 입니다!
it("캐싱은 캐싱의 한계를 넘어가면 메모리에서 삭제되어야 한다. ", async () => {
for (let i = 2; i <= 2 + app.pageMemoryLimit; i++) {
await app.loadPosts(i);
}
await app.loadPosts(2);
expect(mockFetchPosts).toHaveBeenCalledTimes(5);
});
'Study > Frontend' 카테고리의 다른 글
HTTP POST 요청에서 Body에 Null을 보내면 안되는 거에요? (0) | 2025.05.15 |
---|---|
완벽한 페이지네이션 바닥부터 개발하기 EP3 : 리팩토링 (0) | 2024.06.24 |
완벽한 페이지네이션 바닥부터 개발하기 EP2 : 테스트 통과시키기 (1) | 2024.06.19 |
완벽한 페이지네이션 바닥부터 개발하기 EP1 : 개발환경 구축하기 (1) | 2024.06.19 |
2024년에는 라이브러리를 위해 어떤 모듈 번들러를 선택해야 할까? (0) | 2024.04.12 |