본문 바로가기

Study Information Technology

효과적인 페이지네이션과 레이지 로딩 구현하기

728x90
반응형

효과적인 페이지네이션과 레이지 로딩 구현하기

Overview

대규모 콘텐츠를 다루는 웹사이트에서는 사용자 경험을 개선하기 위해 페이지네이션(pagination)과 레이지 로딩(lazy loading) 기법이 필수적입니다. 이러한 기법들은 콘텐츠를 효율적으로 표시하고 로딩 시간을 단축시켜 사용자 참여를 높이는 데 큰 역할을 합니다. 이번 글에서는 페이지네이션과 레이지 로딩의 개념, 구현 방법, 주의해야 할 점들을 자세히 설명하겠습니다.


1. 페이지네이션(Pagination)

1.1 개념

페이지네이션은 콘텐츠를 여러 페이지로 나누어 보여주는 기법입니다. 사용자에게 한 번에 모든 콘텐츠를 로딩하는 대신, 일정 수의 항목만 표시하여 페이지 로딩 속도를 개선합니다. 예를 들어, 100개의 게시글이 있는 블로그가 있다면, 사용자가 한 번에 10개씩 페이지를 이동하여 게시글을 볼 수 있도록 설정합니다.

1.2 구현 예시

다음은 간단한 페이지네이션을 구현하는 방법입니다. 아래의 코드는 React와 Express.js를 활용한 예제입니다.

서버 측 코드 (Express.js)

const express = require('express');
const app = express();

const posts = [...Array(100)].map((_, i) => `Post ${i + 1}`);

app.get('/posts', (req, res) => {
  const page = parseInt(req.query.page) || 1;
  const limit = 10;
  const startIndex = (page - 1) * limit;
  const endIndex = page * limit;

  const resultPosts = posts.slice(startIndex, endIndex);

  res.json({
    totalPosts: posts.length,
    posts: resultPosts,
    currentPage: page,
    totalPages: Math.ceil(posts.length / limit),
  });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

클라이언트 측 코드 (React)

import React, { useEffect, useState } from 'react';

const Posts = () => {
  const [posts, setPosts] = useState([]);
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(0);

  useEffect(() => {
    fetch(`/posts?page=${currentPage}`)
    .then(response => response.json())
    .then(data => {
      setPosts(data.posts);
      setTotalPages(data.totalPages);
    });
  }, [currentPage]);

  return (
    <div>
    <h1>Posts</h1>
    <ul>
    {posts.map(post => (
     <li key={post}>{post}</li>
    ))}
</ul>
<div>
  {Array.from({ length: totalPages }, (_, index) => (
  <button key={index} onClick={() => setCurrentPage(index + 1)}>
  {index + 1}
</button>
))}
</div>
</div>
);
};

export default Posts;

1.3 에러 처리

페이지네이션을 구현할 때, 사용자가 존재하지 않는 페이지에 접근하려고 할 경우 에러가 발생할 수 있습니다. 이 경우, 서버에서는 다음과 같은 메시지를 반환해야 합니다.

if (startIndex >= posts.length) {
  return res.status(404).json({ error: 'Page not found' });
}

2. 레이지 로딩(Lazy Loading)

2.1 개념

레이지 로딩은 사용자가 실제로 콘텐츠를 볼 때까지 해당 콘텐츠의 로딩을 지연시키는 기법입니다. 이는 페이지 로딩 속도를 개선하고 초기 데이터 양을 줄여 사용자 경험을 개선합니다. 예를 들어, 긴 이미지 목록을 표시할 때 사용자가 스크롤할 때마다 해당 이미지가 로드됩니다.

2.2 구현 예시

레이지 로딩을 구현하기 위해 Intersection Observer API를 사용할 수 있습니다. 아래는 React에서 레이지 로딩을 구현하는 예제입니다.

클라이언트 측 코드 (React)

import React, { useEffect, useRef, useState } from 'react';

const LazyLoadImages = () => {
  const [images, setImages] = useState([]);
  const [loaded, setLoaded] = useState(new Set());

  useEffect(() => {
    const imgUrls = [...Array(20)].map((_, i) => `https://placekitten.com/200/200?image=${i}`);
    setImages(imgUrls);
  }, []);

  const handleLoad = (src) => {
    setLoaded((prev) => new Set(prev).add(src));
  };

  return (
    <div>
    <h1>Lazy Load Images</h1>
    <div style={{ height: '800px', overflowY: 'scroll' }}>
    {images.map((src, index) => (
      <div key={index}>
      {loaded.has(src) ? (
        <img src={src} alt={`kitten ${index}`} />
        ) : (
        <img
        src="https://via.placeholder.com/200"
        alt="placeholder"
        ref={(img) => {
        if (img) {
        const observer = new IntersectionObserver(([entry]) => {
        if (entry.isIntersecting) {
        handleLoad(src);
        observer.disconnect();
        }
        });
        observer.observe(img);
        }
        }}
        />
        )}
        </div>
        ))}
        </div>
        </div>
        );
        };

        export default LazyLoadImages;
        ```

        ### 2.3 에러 처리
        레이지 로딩 과정에서 이미지 로딩 실패 시, 대체 이미지를 표시할 수 있도록 처리해야 합니다. 예를 들어, 아래와 같이 `onError` 속성을 사용할 수 있습니다.

        ```javascript
        <img
        src={loaded.has(src) ? src : placeholder}
        alt={`kitten ${index}`}
        onError={() => handleLoad(fallbackImage)}
        />
        ```

        ## 결론
        페이지네이션과 레이지 로딩은 대규모 콘텐츠를 다루는 웹사이트에서 사용자 경험을 개선하는 데 필수적인 기법입니다. 페이지네이션을 통해 콘텐츠를 분할하여 로딩 시간을 단축하고, 레이지 로딩을 통해 사용자가 필요할 때만 콘텐츠를 로드함으로써 효율성을 높일 수 있습니다. 이러한 기법들을 잘 활용한다면, 사용자 참여와 만족도를 크게 향상시킬 수 있습니다.

        ## 참고문서
        - [MDN Web Docs - Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
        - [MDN Web Docs - Pagination](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#pagination)
        - [React Documentation - Using the Effect Hook](https://reactjs.org/docs/hooks-effect.html)
반응형