프론트 개발자를 위한 여정

모든 영역을 안내하는 개발자

Frontend

Next.js와 SSR/ISR부터 테스트, 번들링 최적화, 애니메이션까지: 프론트엔드 개발자의 필수 가이드

ji-frontdev 2025. 1. 17. 11:04
반응형

 

1. Next.js와 SSR/ISR의 이해

Next.js는 React를 기반으로 한 프레임워크로, 서버 사이드 렌더링(SSR)과 정적 사이트 생성(SSG)을 손쉽게 구현할 수 있는 강력한 도구입니다. 특히 ISR(Incremental Static Regeneration)은 동적 컨텐츠를 정적 페이지로 제공하면서도 최신 데이터를 유지할 수 있는 기능을 제공합니다.

SSR vs ISR vs SSG

  • SSR (Server-Side Rendering): 매 요청마다 서버에서 HTML을 생성하여 클라이언트에 전달.
  • ISR (Incremental Static Regeneration): 정적 페이지를 생성한 후, 주기적으로 백그라운드에서 데이터를 갱신.
  • SSG (Static Site Generation): 빌드 시 모든 정적 페이지를 생성, 성능 최적화에 유리.

SSR 코드 예시:

import { GetServerSideProps } from 'next';

export const getServerSideProps: GetServerSideProps = async () => {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();

  return {
    props: { data },
  };
};

const Page = ({ data }) => <div>{data.title}</div>;

export default Page;
 

ISR 코드 예시:

import { GetStaticProps } from 'next';

export const getStaticProps: GetStaticProps = async () => {
  const res = await fetch('https://api.example.com/data');
  const data = await res.json();

  return {
    props: { data },
    revalidate: 10, // 10초마다 갱신
  };
};

const Page = ({ data }) => <div>{data.title}</div>;

export default Page;
 

2. Next.js 동적 라우팅 및 데이터 Fetching 전략

Next.js는 파일 기반 라우팅을 제공하며, 동적 라우팅을 통해 유연한 URL 패턴을 지원합니다.

동적 라우팅 구현 예:

import { useRouter } from 'next/router';

const DynamicPage = () => {
  const router = useRouter();
  const { id } = router.query;

  return <div>Dynamic Page ID: {id}</div>;
};

export default DynamicPage;
 

getStaticPaths와 getStaticProps의 조합:

export async function getStaticPaths() {
  const res = await fetch('https://api.example.com/items');
  const items = await res.json();

  const paths = items.map(item => ({ params: { id: item.id.toString() } }));

  return { paths, fallback: true };
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://api.example.com/item/${params.id}`);
  const item = await res.json();

  return { props: { item } };
}
 

3. 테스팅: Jest, React Testing Library, E2E 테스트

테스트는 소프트웨어 품질을 보장하는 필수적인 요소입니다.

Jest와 React Testing Library를 사용한 유닛 테스트:

import { render, screen } from '@testing-library/react';
import Home from '../pages/index';

test('renders home page', () => {
  render(<Home />);
  const heading = screen.getByText(/Welcome to Next.js/i);
  expect(heading).toBeInTheDocument();
});
 

Cypress를 사용한 E2E 테스트:

describe('Navigation', () => {
  it('should navigate to the about page', () => {
    cy.visit('/');
    cy.get('a[href*="about"]').click();
    cy.url().should('include', '/about');
    cy.get('h1').contains('About Page');
  });
});
 

4. 번들링과 성능 최적화

프론트엔드 성능은 사용자 경험에 큰 영향을 미칩니다. Webpack, Vite, Parcel 등은 번들러로서 코드를 최적화하는 역할을 합니다.

Webpack을 활용한 번들링 최적화:

  • Tree Shaking: 사용되지 않는 코드를 제거하여 번들 크기를 줄임.
  • Code Splitting: 페이지별로 코드를 분리하여 초기 로드 시간을 단축.

Webpack 설정 예시:

module.exports = {
  mode: 'production',
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
    minimize: true,
  },
};
 

5. 애니메이션: Framer Motion과 GreenSock

React 기반 프로젝트에서 매끄러운 애니메이션은 사용자 경험을 향상시킵니다.

Framer Motion 사용 예:

import { motion } from 'framer-motion';

const Example = () => (
  <motion.div
    initial={{ opacity: 0 }}
    animate={{ opacity: 1 }}
    transition={{ duration: 1 }}
  >
    Hello, Framer Motion!
  </motion.div>
);

export default Example;
 

GreenSock 사용 예:

import { useEffect, useRef } from 'react';
import { gsap } from 'gsap';

const Example = () => {
  const boxRef = useRef(null);

  useEffect(() => {
    gsap.to(boxRef.current, { x: 100, duration: 2 });
  }, []);

  return <div ref={boxRef} style={{ width: 100, height: 100, background: 'red' }} />;
};

export default Example;
 

결론

Next.js는 SSR/ISR, 동적 라우팅, 데이터 Fetching 전략 등 현대적인 웹 애플리케이션 개발에 필요한 강력한 기능을 제공합니다. 또한, Jest, React Testing Library, Cypress 등으로 테스팅을 강화하고

Webpack, Vite, Parcel로 번들링을 최적화하며,

Framer Motion과 GreenSock으로 매력적인 애니메이션을 구현할 수 있습니다.

반응형