728x90
반응형
React 애플리케이션을 개발하다 보면 성능 문제가 발생할 때가 있습니다. 특히 컴포넌트의 불필요한 리렌더링은 앱 속도를 저하시킬 수 있는데요, 오늘은 이를 해결하기 위한 성능 최적화 방법과 React에서 제공하는 도구들을 알아보겠습니다! 💡
반응형
1. 리렌더링 최적화의 중요성 🧐
React는 상태나 props가 변경되면 컴포넌트를 리렌더링하는 방식으로 동작합니다. 하지만 모든 리렌더링이 필요한 것은 아니죠. 불필요한 리렌더링을 줄이면 애플리케이션의 성능을 크게 개선할 수 있습니다.
리렌더링이 발생하는 이유
- 부모 컴포넌트가 리렌더링될 때 자식 컴포넌트도 리렌더링됨.
- props나 상태(state)가 변경될 때.
- 동일한 데이터를 다시 계산하거나 처리할 때.
2. React.memo로 컴포넌트 메모화하기 🧠
React.memo는 컴포넌트를 메모화(memoization)하여 동일한 props가 전달되면 이전 결과를 재사용하도록 합니다.
예제: React.memo 사용하기
import React from 'react';
const ChildComponent = React.memo(({ value }) => {
console.log('ChildComponent Rendered');
return <div>Value: {value}</div>;
});
function ParentComponent() {
const [count, setCount] = React.useState(0);
const [text, setText] = React.useState('');
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<ChildComponent value={count} />
</div>
);
}
export default ParentComponent;
이 코드의 동작
- ChildComponent는 value props가 변경될 때만 리렌더링됩니다.
- React.memo를 사용하지 않으면 text가 변경될 때도 리렌더링이 발생합니다.
3. useMemo로 값 메모화하기 📦
useMemo는 계산 비용이 높은 연산을 메모화하여 불필요한 재계산을 방지합니다.
예제: useMemo 사용하기
import React, { useMemo, useState } from 'react';
function ExpensiveComponent({ number }) {
const expensiveCalculation = useMemo(() => {
console.log('Calculating...');
return number * 2;
}, [number]);
return <div>Result: {expensiveCalculation}</div>;
}
function App() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
/>
<ExpensiveComponent number={count} />
</div>
);
}
export default App;
이 코드의 동작
- number가 변경될 때만 expensiveCalculation이 다시 실행됩니다.
- 입력값이 변경되어도 메모된 결과를 재사용합니다.
4. useCallback으로 함수 메모화하기 ✨
useCallback은 함수를 메모화하여 동일한 함수를 재사용하도록 합니다. 이를 통해 자식 컴포넌트로 전달되는 함수를 최적화할 수 있습니다.
예제: useCallback 사용하기
import React, { useState, useCallback } from 'react';
const ChildComponent = React.memo(({ onClick }) => {
console.log('ChildComponent Rendered');
return <button onClick={onClick}>Click Me</button>;
});
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
console.log('Button clicked');
}, []);
return (
<div>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
<ChildComponent onClick={handleClick} />
</div>
);
}
export default ParentComponent;
이 코드의 동작
- handleClick은 메모화되어 동일한 참조를 유지합니다.
- ChildComponent는 부모 컴포넌트가 리렌더링돼도 다시 렌더링되지 않습니다.
5. 실제 사례: 무한 스크롤 구현하기 📜
성능 최적화의 대표적인 예로 무한 스크롤이 있습니다. 데이터를 불러올 때 필요한 부분만 로드하여 성능을 개선할 수 있습니다.
예제: 무한 스크롤 구현
import React, { useState, useEffect } from 'react';
function InfiniteScroll() {
const [items, setItems] = useState([]);
const [page, setPage] = useState(1);
useEffect(() => {
const fetchItems = async () => {
const newItems = Array.from({ length: 10 }, (_, i) => `Item ${i + 1 + (page - 1) * 10}`);
setItems((prevItems) => [...prevItems, ...newItems]);
};
fetchItems();
}, [page]);
const handleScroll = () => {
if (window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight) {
setPage((prevPage) => prevPage + 1);
}
};
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
return (
<div>
<h1>Infinite Scroll</h1>
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
export default InfiniteScroll;
이 코드의 동작
- 스크롤이 하단에 도달하면 page 상태가 업데이트됩니다.
- page가 변경될 때마다 새로운 데이터를 불러옵니다.
- 기존 데이터는 유지하면서 새 데이터를 추가합니다.
6. 마무리 🎉
React 애플리케이션의 성능 최적화는 사용자 경험을 개선하는 중요한 단계입니다. 오늘 배운 React.memo, useMemo, useCallback을 활용하면 불필요한 리렌더링을 줄이고 더 빠르고 효율적인 애플리케이션을 만들 수 있습니다. 🚀
실제 프로젝트에서 이런 기법을 적용해보고, 더 나은 성능을 경험해보세요! 💪
728x90
반응형
'React' 카테고리의 다른 글
[React] TypeScript로 React 개발 완전 정복하기! 🚀 (0) | 2024.12.31 |
---|---|
[React] Context API vs Redux – 어떤 상태 관리 방법이 더 나을까? 😳 (0) | 2024.12.31 |
[React] 폼 처리와 유효성 검사 완벽하게 처리하는 방법 💻 (0) | 2024.12.30 |
[React] React Router로 SPA 만들기 – 페이지 전환 완벽 가이드 🚀 (0) | 2024.12.29 |
[React] Context API로 글로벌 상태 관리 마스터하기! 🌍 (0) | 2024.12.28 |