Notice
Recent Posts
Recent Comments
Link
솔미는 성장중
오히려 컴포넌트를 나눴더니 성능이 떨어진다? : 컴포넌트 최적화하기 (reactMemo & useCallback & useMemo) 본문
react
오히려 컴포넌트를 나눴더니 성능이 떨어진다? : 컴포넌트 최적화하기 (reactMemo & useCallback & useMemo)
solming 2023. 8. 25. 05:28728x90
문제 상황
오히려 컴포넌트를 나눴더니 성능이 떨어진다?
이것은 렌더링이 최적화되어있지 않기 때문이다.
props가 변화하는 곳만 렌더링 해주면 되는데 전부 다 렌더링하고 있는 경우 이런 현상이 발생한다.
해결법
React.memo
컴포넌트를 React.memo()로 둘러싸면 컴포넌트를 메모이징한다.
props가 바뀌지 않은 컴포넌트는 새롭게 렌더링되지 않고 메모이징 된 내용을 재사용한다.
언제 사용하면 좋을까?
- 새로 업데이트를 잘 시키지 않아도 되는 컴포넌트
예시
const List = React.memo(({ posts, testFunction }) => {
console.log("List Component");
return (
<ul>
{posts.map((post) => (
<ListItem key={post.id} post={post} />
))}
</ul>
);
});
useCallback
함수 자체를 메모이징 한다.
왜 사용할까?
- 최적화
- 처리 시간을 빠르게 하기 위해 코드를 효율적으로 처리하게 만들어준다.
- 컴포넌트가 새롭게 렌더링 된다해서 똑같은 함수를 계속 다시 만드는 것은 비효율적.(해당 함수를 내려받은 자녀 컴포넌트도 새롭게 렌더링 되게 때문에..) -> 이러한 함수는 재생성하지 않게 만들어준다.
언제 사용하면 좋을까?
- 해당 함수를 다른 컴포넌트로 내려줬을 때
- 의존성 배열[ ]가 자주 바뀌지 않을 때
useMemo
함수의 리턴값을 메모이징한다.
(useCallback과 매우 유사)
언제 사용하면 좋을까?
- 함수 내에서 heavy한 계산을 하는 경우
성능 비교 예제 코드) A는 통으로 작성, B는 컴포넌트화 (+최적화된 상태)
App.js
import "./App.css";
import { useEffect, useState } from "react";
import A from "./components/A";
import B from "./components/B";
function App() {
const [value, setvalue] = useState("");
//jsonplaceholder 데이터를 GET하기 위한 요청 보내기
const [posts, setPosts] = useState([]);
useEffect(() => {
//백엔드 api에 요청보내기
//비동기 요청
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((posts) => setPosts(posts)); //데이터 기억 => state사용
}, []); // 종속성 배열에 아무것도 없으면 한번만 실행
return (
<div style={{ padding: "2rem" }}>
<input value={value} onChange={(e) => setvalue(e.target.value)} />
<div style={{ display: "flex" }}>
<A message={value} posts={posts} />
<B message={value} posts={posts} />
</div>
</div>
);
}
export default App;
A.js
import React from "react";
const A = ({ message, posts }) => {
return (
<div>
<h1>A Component</h1>
<p>{message}</p>
<ul>
{posts.map((post) => {
return (
<li key={post.id}>
<p>{post.title}</p>
</li>
);
})}
</ul>
</div>
);
};
export default A;
B.js
import React, { useCallback } from "react";
const Message = React.memo(({ message }) => {
console.log("Message Component");
return <p>{message}</p>;
});
const ListItem = React.memo(({ post }) => {
console.log("ListItem Component");
return (
<li>
<p>{post.title}</p>
</li>
);
});
const List = React.memo(({ posts, testFunction }) => {
console.log("List Component");
return (
<ul>
{posts.map((post) => (
<ListItem key={post.id} post={post} />
))}
</ul>
);
});
const B = ({ message, posts }) => {
console.log("B component");
const testFunction = useCallback(() => {}, []); //B컴포넌트 렌더링 => testFunction 함수 재생성 => List 자녀 Props => List 컴포넌트 렌더링
return (
<div>
<h1>B Component</h1>
<Message message={message} />
<List posts={posts} testFunction={testFunction} />
</div>
);
};
export default B;
728x90
'react' 카테고리의 다른 글
[React] Reducer (0) | 2023.10.15 |
---|---|
[React] UI를 React로 재구현하는 과정 / State 보존 및 재설정 (0) | 2023.10.14 |
[React] 렌더링 (UI를 요청하고 제공하는 3단계) (0) | 2023.09.06 |
[React] 추가 정보 (spa, 불변성, react hooks) (0) | 2023.08.30 |
[React] React 기본 개념 (0) | 2023.08.06 |