81일
- react 렌더링 최적화 memoization
컴퓨터가 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로서 동일한 계산을 하지 않도록 하여, 속도를 높이는 기술이다. 보통 애플리케이션의 최적화를 위해 사용된다.
- React.memo (memo) : 컴포넌트 를 캐싱 (기억한다.)
- useCallback : 함수를 캐싱
- usememo : 값을 캐싱
부모 컴포넌트가 리렌더링 되면 자식컴포넌트 모두 리렌더링 된다.
export default function App() {
console.log("App 컴포넌트 렌러링");
const [count, setCount] = useState(0);
const onClickPlus = () => {
setCount(count + 1);
};
const onClickMinus = () => {
setCount(count - 1);
};
return (
<div className="App">
<h3>카운트</h3>
<p>현재 카운트 {count}</p>
<button onClick={onClickPlus}>+1 </button>
<button onClick={onClickMinus}>-1 </button>
{/* 자식컴포넌트 */}
<div style={boxesStyle}>
<Box1 />
<Box2 />
<Box3 />
</div>
</div>
);
}
function Box1() {
console.log("Box1이 렌더링 되었습니다.");
return <div style={boxStyle}>Box1</div>;
}
export default memo(Box1); //import 했을경우
/*
export default React.memo(Box1) //import 안했을 경우
*/
useCallback 은 인자로 들어오는 함수 자체를 기억(memoization)한다.
-App.jsx
console.log("App 컴포넌트 렌러링");
const [count, setCount] = useState(0);
//초기화 버튼
const initCount = () => {
setCount(0);
};
const onClickPlus = () => {
setCount(count + 1);
};
const onClickMinus = () => {
setCount(count - 1);
};
return (
<div className="App">
<h3>카운트</h3>
<p>현재 카운트 {count}</p>
<button onClick={onClickPlus}>+1 </button>
<button onClick={onClickMinus}>-1 </button>
{/* 자식컴포넌트 */}
<div style={boxesStyle}>
<Box1 initCount={initCount} />
<Box2 />
<Box3 />
</div>
</div>
);
function Box1({ initCount }) {
console.log("Box1이 렌더링 되었습니다.");
const onInitButton = () => {
initCount();
};
return (
<div style={boxStyle}>
<button onClick={onInitButton}>초기화</button>
</div>
);
}
export default memo(Box1);
const onInitButton = useCallback(() => {
initCount();
},[]);
const initCount = useuseCallback3Callback(() => {
console.log(`count가 ${count}에서 0으로 변경되었습니다.`);
setCount(0);
}, [count]);
값(객체, 배열, 함수)을 기억한다.
동일한 값을 반환하는 함수를 계속 호출해야 할때, 이전에 계산한 값을 메모리에 저장 함으로써 동일한 계산의 반복 수행을 제거 하여 프로그램 속도를 빠르게 한다.
import { useState } from "react";
const hardCalculate = (number) => {
console.log("어려운 계산!");
for (let i = 0; i < 99999999; i++) {} // 생각하는 시간
return number + 10000;
};
const easyCalculate = (number) => {
console.log("쉬운 계산!");
return number + 1;
};
function App() {
const [hardNumber, setHardNumber] = useState(1);
const [easyNumber, setEasyNumber] = useState(1);
const hardSum = useMemo(()=>hardCalculate(hardNumber),[]);
const easySum = easyCalculate(easyNumber);
return (
<div>
<h3>어려운 계산기</h3>
<input
type="number"
value={hardNumber}
onChange={(e) => setHardNumber(parseInt(e.target.value))}
/>
<span> + 10000 = {hardSum}</span>
<h3>쉬운 계산기</h3>
<input
type="number"
value={easyNumber}
onChange={(e) => setEasyNumber(parseInt(e.target.value))}
/>
<span> + 1 = {easySum}</span>
</div>
);
}
export default App;
import { useMemo, useEffect, useState } from 'react';
function App() {
const [number, setNumber] = useState(0);
const [isKorea, setIsKorea] = useState(true);
// const location = { country: isKorea ? '한국' : '일본' };
const location = useMemo(() => {
return {
//객체 타입
country: isKorea ? '한국' : '일본'
}
}, [isKorea])
useEffect(() => {
console.log('useEffect... 호출');
// 뭔가 오래 걸리는 작업
}, [location])
return (
<header className="App-header">
<h2>하루에 몇 끼 먹어요?</h2>
<input type="number" value={number} onChange={(e) => setNumber(e.target.value)}/>
<hr/>
<h2>어느 나라에 있어요?</h2>
<p>나라: {location.country}</p>
<button onClick={() => setIsKorea(!isKorea)}>Update</button>
</header>
);
}
export default App;
useMemo를 남발하게 되면 별도의 메모리 확보가 너무나 많이 하게 되기 때문에 오리혀 성능이 악화될 수 있따. 필요할 때만 사용하는 것이 좋다.