React와 Node.js를 사용한 웹 애플리케이션 개발

React와 Node.js를 사용한 웹 애플리케이션(게시판) 개발 강좌(29)

atomicdev 2024. 9. 22. 22:01
728x90

성능 최적화: React 및 Node.js 성능 최적화 기법

이번 강의에서는 ReactNode.js 애플리케이션에서 성능을 최적화하는 기법을 다룹니다. 성능을 최적화하면 애플리케이션이 더 빠르고 효율적으로 동작할 수 있습니다. 특히, React에서 컴포넌트 렌더링 최적화와 Node.js에서 서버 처리 성능 향상을 위해 다양한 방법을 사용할 수 있습니다.

React와 Node.js 에서 성능 최적화


1. React 성능 최적화 기법

React는 컴포넌트 기반 라이브러리로, 컴포넌트가 렌더링될 때 불필요한 렌더링을 방지하는 것이 성능 최적화의 핵심입니다.

1.1 React.memo

React.memo는 불필요한 컴포넌트 재렌더링을 방지하는 데 유용한 고차 컴포넌트(HOC)입니다. props가 변경되지 않은 경우, 컴포넌트를 다시 렌더링하지 않고 이전 결과를 재사용합니다.

import React from 'react';

const MyComponent = React.memo(({ name }) => {
  console.log('렌더링됨');
  return <div>{name}</div>;
});

export default MyComponent;
  • 사용 방법: React.memo를 사용하여 부모 컴포넌트에서 전달된 props가 변경되지 않는다면, 자식 컴포넌트의 재렌더링을 방지할 수 있습니다.

1.2 useMemo

useMemo는 특정 값의 계산 비용이 높은 경우, 메모이제이션을 통해 이전에 계산된 값을 재사용하도록 도와줍니다. 즉, 의존성이 변경되지 않으면 함수의 반환 값을 캐싱하여 성능을 최적화합니다.

import React, { useMemo } from 'react';

const MyComponent = ({ items }) => {
  // items가 변경될 때만 계산 수행
  const sortedItems = useMemo(() => {
    console.log('정렬 중...');
    return items.sort();
  }, [items]);

  return (
    <ul>
      {sortedItems.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
};

export default MyComponent;
  • 사용 방법: 데이터 정렬이나 계산이 빈번하게 발생하는 경우, useMemo를 사용하여 성능을 개선할 수 있습니다.

1.3 useCallback

useCallback은 함수형 컴포넌트를 최적화하기 위한 훅으로, 함수가 다시 생성되는 것을 방지합니다. props로 전달되는 함수가 불필요하게 다시 생성되는 것을 방지하여, 자식 컴포넌트의 재렌더링을 줄일 수 있습니다.

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

const MyButton = React.memo(({ onClick }) => {
  console.log('버튼 렌더링됨');
  return <button onClick={onClick}>클릭</button>;
});

const ParentComponent = () => {
  const [count, setCount] = useState(0);

  // useCallback을 사용하여 함수 메모이제이션
  const handleClick = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      <MyButton onClick={handleClick} />
    </div>
  );
};

export default ParentComponent;
  • 사용 방법: useCallback을 사용하면 동일한 함수가 계속해서 재생성되지 않으며, 자식 컴포넌트에 전달되는 함수를 메모이제이션하여 성능을 향상시킬 수 있습니다.

2. Node.js 성능 최적화 기법

2.1 비동기 처리 최적화

Node.js는 비동기 I/O를 기반으로 동작하므로, 비동기 함수를 적절히 사용하면 성능을 크게 향상시킬 수 있습니다. 특히, 데이터베이스 쿼리나 파일 읽기/쓰기 같은 I/O 작업에서 비동기 함수를 사용하는 것이 중요합니다.

// 비동기 함수 사용
const fs = require('fs').promises;

async function readFile() {
  try {
    const data = await fs.readFile('/path/to/file', 'utf8');
    console.log(data);
  } catch (error) {
    console.error('파일 읽기 오류:', error);
  }
}

2.2 클러스터링을 통한 병렬 처리

Node.js는 기본적으로 싱글 스레드에서 동작하지만, **클러스터링(clustering)**을 통해 멀티 코어 CPU를 활용할 수 있습니다. cluster 모듈을 사용하여 여러 인스턴스를 생성하면, 서버의 부하를 분산시킬 수 있습니다.

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // 각 CPU 코어에 워커를 생성
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  // 워커는 HTTP 서버를 실행
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('Hello World\n');
  }).listen(8000);
}

2.3 캐싱을 통한 응답 속도 향상

데이터베이스 쿼리나 외부 API 호출이 빈번할 경우, 캐싱을 사용하여 성능을 최적화할 수 있습니다. Node.js에서는 Redis메모리 캐싱을 사용하여 자주 사용되는 데이터를 캐싱할 수 있습니다.

const redis = require('redis');
const client = redis.createClient();

async function getCachedData(key) {
  return new Promise((resolve, reject) => {
    client.get(key, (err, data) => {
      if (err) return reject(err);
      resolve(data);
    });
  });
}

async function fetchData() {
  const cacheKey = 'my_data';
  const cachedData = await getCachedData(cacheKey);

  if (cachedData) {
    console.log('캐시된 데이터:', cachedData);
  } else {
    const newData = await fetchFromDatabase();
    client.set(cacheKey, newData); // 캐싱
  }
}

3. 성능 최적화의 Best Practices

3.1 코드 분할

React 애플리케이션에서 **코드 스플리팅(code splitting)**을 사용하여 필요한 코드만 로드할 수 있도록 합니다. React.lazy와 Suspense를 활용하여 특정 컴포넌트를 필요할 때만 로드하면 초기 로딩 속도를 개선할 수 있습니다.

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </React.Suspense>
  );
}

3.2 데이터베이스 최적화

Node.js 애플리케이션에서 데이터베이스 쿼리를 최적화하면 서버 응답 속도를 개선할 수 있습니다. 인덱스를 적절히 설정하거나, 불필요한 데이터 로드를 방지하는 쿼리 구조를 사용할 수 있습니다.

3.3 애플리케이션 모니터링

서버 성능을 지속적으로 모니터링하기 위해 PM2와 같은 도구를 사용하여 CPU, 메모리 사용량을 체크하고, 애플리케이션 병목 현상을 파악할 수 있습니다.


결론

이번 강의에서는 ReactNode.js 애플리케이션에서 성능을 최적화하는 다양한 기법을 다루었습니다. React에서 memoization비동기 처리를 통해 불필요한 렌더링을 방지하고, Node.js에서는 비동기 처리, 클러스터링, 캐싱을 통해 서버 성능을 향상시키는 방법을 배웠습니다.

728x90