
Infinite Scroll(무한 스크롤)은 사용자가 페이지 하단까지 스크롤할 때 추가 데이터를 비동기로 불러와 계속해서 콘텐츠가 로드되는 UX 패턴이다. 이 방식은 SNS나 뉴스 앱과 같은 서비스에서 많이 사용된다. 페이지 리로드 없이 연속적으로 데이터를 가져와 사용자 경험을 개선하는 방식이다.
주요 요소
scroll 이벤트 리스너fetch, axios 등)DOM 조작 및 데이터 추가 렌더링Loading Indicator)<!-- HTML 구조 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Infinite Scroll</title>
</head>
<body>
<div id="content-container"></div>
<div id="loader" style="text-align:center; display:none;">🔄 Loading...</div>
<script>
// Infinite Scroll 구현
const contentContainer = document.getElementById("content-container");
const loader = document.getElementById("loader");
// 상태 변수
let currentPage = 1; // 현재 페이지
let isLoading = false; // 데이터 요청 상태 관리 변수
/**
* 데이터를 가져오는 함수 (비동기)
*/
async function fetchData() {
try {
// 로딩 상태 true 설정 및 표시
isLoading = true;
loader.style.display = "block";
// API 데이터 호출 (더미 데이터 활용 예시)
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?_limit=10&_page=${currentPage}`
);
const data = await response.json();
// 데이터 렌더링
renderData(data);
currentPage++;
} catch (error) {
console.error("Error fetching data: ", error);
} finally {
isLoading = false;
loader.style.display = "none"; // 로딩 메시지 숨기기
}
}
/**
* 데이터를 DOM에 추가 렌더링하는 함수
*/
function renderData(data) {
data.forEach((item) => {
const contentDiv = document.createElement("div");
contentDiv.classList.add("post");
contentDiv.style.margin = "10px";
contentDiv.style.padding = "15px";
contentDiv.style.border = "1px solid #ddd";
contentDiv.innerHTML = `
<h3>${item.title}</h3>
<p>${item.body}</p>
`;
contentContainer.appendChild(contentDiv);
});
}
/**
* 스크롤 이벤트 핸들러
*/
function handleScroll() {
// 페이지 끝에 도달했는지 확인
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 10 && !isLoading) {
fetchData(); // 추가 데이터 호출
}
}
// 초기 데이터 로드
fetchData();
// 스크롤 이벤트 등록
window.addEventListener("scroll", handleScroll);
</script>
</body>
</html>
초기 데이터 로드
fetchData() 함수는 페이지가 처음 로드될 때 한 번 호출된다.API에서 데이터를 가져오며 페이지 번호는 currentPage로 관리된다.데이터 호출(fetch API)
API 호출을 통해 10개의 데이터를 가져온다. (?_limit=10&_page=${currentPage})const response = await fetch(
`https://jsonplaceholder.typicode.com/posts?_limit=10&_page=${currentPage}`
);
DOM에 렌더링
content-container에 추가된다.renderData(data);스크롤 이벤트 감지
handleScroll() 이벤트 핸들러가 호출된다.window.addEventListener("scroll", handleScroll);
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 10 && !isLoading) {
fetchData();
}
비동기 처리 및 상태 관리
isLoading 변수를 활용해 중복 호출을 방지한다.스크롤 최적화
scroll 이벤트는 매우 빈번하게 호출되기 때문에 최적화가 필요하다.debounce 또는 throttle 기법을 사용하여 스크롤 이벤트 호출 빈도를 줄인다.로딩 상태 표시
loader.style.display = "block";Infinite Scroll은 비동기 API 호출로 연속적으로 데이터를 로드하는 UX 패턴이다.debounce, throttle, IntersectionObserver와 같은 기법을 활용할 수 있다.Infinite Scroll은 SNS나 뉴스 페이지 같은 콘텐츠가 많은 웹사이트에서 유용하게 사용된다. 그러나 UX와 성능을 최적화하는 것이 중요하다.