문제
- 개요
- 상품 리스트 페이지에서 상품을 클릭해 상세 페이지로 이동 후, 뒤로가기 버튼을 눌렀을 때 페이지가 새로고침되면서 리스트의 상단으로 이동하기 때문에 UX가 떨어진다는 피드백을 받음.
- 페이지에 카테고리와 필터가 중복으로 적용되고 있고 상품 데이터의 양이 많아 서버로부터 많은 리소스를 받아와야 함.
- 위치값 사용의 문제
- 화면의 높이값을 저장했다가 불러와서 로드해주는 방법을 사용했지만 새로고침이 되고 그 위치까지 자동으로 스크롤 되는 액션이 발생함
- 위치까지 빠르게 이동하면서 그 사이의 데이터를 빠르게 받아와 보여주는 과정에서 많은 리소스가 낭비됨
- 기획자의 요구사항
- 새로고침 없이 이전 리스트 화면을 보여주기를 원함.
- 현재는 페이지 위치값을 넘겨서 스크롤하는 방식으로 구현됨.
- 런칭이 임박했고, 런칭 후 이벤트 때문에 유저가 본 상품의 상태가 정확하게 반영될 필요가 있음.
- 향후 계획
- 런칭 후 이슈 해결을 위해 캐싱 전략이나 데이터 동기화 방식 등 다양한 기술적 해결책을 고민할 예정.
해결방법
캐싱된 데이터를 기반으로 페이지를 먼저 로드하고, 백그라운드에서 실시간 데이터를 동기화하는 방법
1. 데이터 요청 및 캐싱
먼저, 상품 리스트 페이지 컴포넌트를 작성
이 컴포넌트는 서버에서 데이터를 받아오고, 로컬 스토리지에 저장한 후, 데이터를 렌더링.
2. 캐싱된 데이터로 페이지 로드 및 실시간 데이터 동기화
캐싱된 데이터가 있으면 먼저 이를 사용해 페이지를 렌더링, 백그라운드에서 실시간 데이터를 요청하여 데이터를 갱신.
3. 오류 처리 및 데이터 유효성 검사
서버 요청이 실패하면 캐싱된 데이터를 사용, 캐시된 데이터의 유효성을 주기적으로 검사하여 오래된 데이터를 제거.
import React, { useEffect, useState } from 'react';
const ProductList = () => {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
// 로컬 스토리지에서 캐싱된 데이터 불러오기
const cachedData = localStorage.getItem('productList');
if (cachedData) {
setProducts(JSON.parse(cachedData));
setLoading(false);
}
// 서버에서 실시간 데이터 요청
fetch('/api/products')
.then(response => response.json())
.then(data => {
setProducts(data);
setLoading(false);
localStorage.setItem('productList', JSON.stringify(data));
localStorage.setItem('cacheTime', new Date().getTime());
})
.catch(error => {
console.error('데이터를 불러오는데 실패했습니다.', error);
setLoading(false);
});
}, []);
// 캐시 유효성 검사
useEffect(() => {
const cacheTime = localStorage.getItem('cacheTime');
const now = new Date().getTime();
const CACHE_VALIDITY_DURATION = 1000 * 60 * 60 * 24; // 1일
if (cacheTime && now - cacheTime > CACHE_VALIDITY_DURATION) {
localStorage.removeItem('productList');
localStorage.removeItem('cacheTime');
}
}, []);
if (loading) {
return <div>Loading...</div>;
}
return (
<div id="product-list">
{products.map(product => (
<div className="product-item" key={product.id}>
<h2>{product.name}</h2>
<p>{product.description}</p>
<span>{product.price}</span>
</div>
))}
</div>
);
};
export default ProductList;
'2024 > TIL' 카테고리의 다른 글
[AWS TechCamp] AWS 서버리스로 서버 고민 없이 웹 애플리케이션 구축하기 (2) | 2024.09.04 |
---|---|
[CSS] BEM(Block, Element, Modifier) 모델 (0) | 2024.08.29 |
[독서] 선물받은 「나는 네이버 프런트엔드 개발자입니다」 책 읽기 (0) | 2024.08.23 |
[cs] Observer Pattern 왜 알아야 할까? (1) | 2024.07.11 |
[React] 쉽지 않은 유효성 검사(Debouncing, Throttling) (0) | 2024.06.23 |