[infiniteScroll 기법] 비동기로 데이터를 가져와서 처리하는 방법으로 infiniteScroll 기법을 사용하는 방법

박찬정·2024년 7월 8일
0

Infinite Scroll 기법은 사용자가 페이지를 스크롤할 때 자동으로 더 많은 데이터를 비동기적으로 가져와서 현재 콘텐츠에 추가하는 방식입니다. 이 방법은 주로 소셜 미디어 피드, 상품 목록, 게시물 목록 등에서 사용됩니다. Infinite Scroll의 기본 개념과 구현 방법을 단계별로 설명하겠습니다.

1. 기본 개념

목표: 사용자가 페이지를 스크롤할 때 추가 데이터를 비동기적으로 가져와서 화면에 추가하는 것.
이점: 사용자는 명시적으로 "더 보기" 버튼을 클릭할 필요 없이 계속해서 콘텐츠를 탐색할 수 있습니다.
단점: 많은 데이터를 한 번에 로드할 경우 성능 문제가 발생할 수 있으며, 페이지의 끝을 찾기 어려울 수 있습니다.

2. 구현 방법

Step 1: 기본 HTML 구조 및 초기 데이터 로드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Infinite Scroll Example</title>
    <style>
        #content {
            max-width: 600px;
            margin: 0 auto;
        }
        .item {
            padding: 20px;
            border: 1px solid #ddd;
            margin: 10px 0;
        }
    </style>
</head>
<body>
    <div id="content">
        <!-- 데이터 항목이 여기에 추가됩니다. -->
    </div>
    <script src="app.js"></script>
</body>
</html>

Step 2: JavaScript로 데이터 로드 및 렌더링

// app.js
document.addEventListener('DOMContentLoaded', () => {
    const content = document.getElementById('content');
    let page = 1;

    // 데이터를 비동기로 가져오는 함수
    async function fetchData(page) {
        const response = await fetch(`https://api.example.com/data?page=${page}`);
        const data = await response.json();
        return data;
    }

    // 데이터를 DOM에 추가하는 함수
    function renderData(data) {
        data.forEach(item => {
            const div = document.createElement('div');
            div.className = 'item';
            div.textContent = item.text;
            content.appendChild(div);
        });
    }

    // 초기 데이터 로드
    async function loadInitialData() {
        const initialData = await fetchData(page);
        renderData(initialData);
        page++;
    }

    loadInitialData();

    // 스크롤 이벤트 핸들러
    window.addEventListener('scroll', async () => {
        if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 100) {
            const newData = await fetchData(page);
            renderData(newData);
            page++;
        }
    });
});

3. 상세 설명

데이터 비동기 로드

fetchData 함수: 이 함수는 현재 페이지 번호를 받아 해당 페이지의 데이터를 가져옵니다.
fetch API: 브라우저 내장 API로, 네트워크 요청을 수행하여 데이터를 가져옵니다.
await 및 async: 비동기 함수 내에서 사용되며, 네트워크 요청이 완료될 때까지 기다립니다.
데이터 렌더링
renderData 함수: 가져온 데이터를 DOM에 추가합니다.
DOM 조작: 각 데이터 항목에 대해 새로운 <div> 요소를 생성하고, 데이터를 채운 후 content 요소에 추가합니다.

스크롤 이벤트 처리

window.addEventListener('scroll', async () => {...}): 스크롤 이벤트를 감지하여 사용자가 페이지의 거의 끝에 도달했을 때 추가 데이터를 가져옵니다.
스크롤 위치 계산: window.innerHeight + window.scrollY >= document.body.offsetHeight - 100는 현재 스크롤 위치가 문서의 끝에 가까운지 확인합니다.
데이터 추가 로드: 조건을 만족하면 새로운 데이터를 가져와 렌더링합니다.

4. 추가 고려사항

로딩 인디케이터

사용자가 추가 데이터를 기다리는 동안 로딩 인디케이터를 표시하여 UX를 개선할 수 있습니다.

<div id="loading" style="text-align: center; display: none;">
    <p>Loading...</p>
</div>
// 스크롤 이벤트 핸들러
window.addEventListener('scroll', async () => {
    if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 100) {
        document.getElementById('loading').style.display = 'block';
        const newData = await fetchData(page);
        renderData(newData);
        document.getElementById('loading').style.display = 'none';
        page++;
    }
});

끝에 도달한 경우

모든 데이터를 로드한 경우 추가 요청을 중단하는 로직을 추가해야 합니다.

let allDataLoaded = false;

window.addEventListener('scroll', async () => {
    if (allDataLoaded) return;

    if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 100) {
        document.getElementById('loading').style.display = 'block';
        const newData = await fetchData(page);
        if (newData.length === 0) {
            allDataLoaded = true;
            document.getElementById('loading').textContent = 'No more data';
        } else {
            renderData(newData);
            document.getElementById('loading').style.display = 'none';
            page++;
        }
    }
});

요약
Infinite Scroll은 사용자 경험을 개선할 수 있는 강력한 기법이지만, 구현 시 성능 문제와 UX를 신경 써야 합니다. 위의 예시를 통해 기본적인 Infinite Scroll을 구현하는 방법을 이해하고, 추가적인 고려사항을 통해 최적화된 사용자 경험을 제공할 수 있습니다.

profile
프론트엔드 배우고 있습니다

0개의 댓글