Memoization

Reactμ—μ„œλŠ” μƒμœ„ μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λ Œλ”λ§λ˜κ±°λ‚˜, ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈμ˜ μƒνƒœκ°€ λ³€κ²½λœ κ²½μš°μ— λ¦¬λ Œλ”λ§μ„ μˆ˜ν–‰ν•œλ‹€.

λΆˆν•„μš”ν•œ λ¦¬λ Œλ”λ§

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

  return (
    <div>
      <Description />
      <CounterButton
        count={count}
        onClick={() => setCount((prev) => prev + 1)}
      />
    </div>
  );
};

const CounterButton = ({ count, onClick }) => {
  return <button onClick={onClick}>Clicked {count} times!</button>;
};

const Description = () => {
  return <p>Click the button</p>;
};

μœ„μ˜ μ½”λ“œλŠ” λ²„νŠΌμ„ ν΄λ¦­ν–ˆμ„ λ•Œ countκ°€ 1μ”© λ”ν•΄μ§€λŠ” κ°„λ‹¨ν•œ μ˜ˆμ œμ΄λ‹€. λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄ App, CounterButton, Description μ»΄ν¬λ„ŒνŠΈκ°€ λͺ¨λ‘ λ¦¬λ Œλ”λ§λœλ‹€.

κ·ΈλŸ¬λ‚˜ Description μ»΄ν¬λ„ŒνŠΈκ°€ λ‹€μ‹œ λ¦¬λ Œλ”λ§λ˜μ–΄μ•Ό ν•  ν•„μš”κ°€ μžˆμ„κΉŒ? Description μ»΄ν¬λ„ŒνŠΈλŠ” count의 변경에 관계없이 λ™μΌν•œ 결과둜 λ Œλ”λ§λ  것이닀. λ§Œμ•½ Description μ»΄ν¬λ„ŒνŠΈκ°€ λ§Žμ€ ν•˜μœ„ μ»΄ν¬λ„ŒνŠΈ λ˜λŠ” λ‘œμ§μ„ ν¬ν•¨ν•˜κ³  μžˆμ–΄ λ¦¬λ Œλ”λ§ν•˜λŠ” 데 λ§Žμ€ λ¦¬μ†ŒμŠ€κ°€ μ†Œμš”λœλ‹€λ©΄, λΆˆν•„μš”ν•œ λ¦¬λ Œλ”λ§μ— μ˜ν•œ μ„±λŠ₯ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλ‹€.

μ΄λŸ¬ν•œ 'λΆˆν•„μš”ν•œ λ¦¬λ Œλ”λ§' 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ Reactμ—μ„œλŠ” μ»΄ν¬λ„ŒνŠΈ, κ°’, ν•¨μˆ˜λ₯Ό λ©”λͺ¨μ΄μ œμ΄μ…˜ν•˜λŠ” memo, useMemo, useCallback APIλ₯Ό μ œκ³΅ν•œλ‹€.

memo

μ»΄ν¬λ„ŒνŠΈμ˜ propsκ°€ λ³€κ²½λ˜μ§€ μ•Šμ€ 경우, μ»΄ν¬λ„ŒνŠΈ λ¦¬λ Œλ”λ§μ„ κ±΄λ„ˆλ›Έ 수 있게 ν•œλ‹€. - React 곡식 λ¬Έμ„œ

λΆˆν•„μš”ν•œ λ¦¬λ Œλ”λ§μ˜ μ˜ˆμ œμ—μ„œ, count μƒνƒœμ˜ λ³€κ²½μœΌλ‘œ μΈν•œ Description μ»΄ν¬λ„ŒνŠΈμ˜ λ¦¬λ Œλ”λ§μ„ λ§‰λŠ” 데 memoλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

Description μ»΄ν¬λ„ŒνŠΈλ₯Ό μœ„μ™€ 같이 λ³€κ²½ν•˜λ©΄, CounterButton을 클릭해도 Description μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λ Œλ”λ§λ˜μ§€ μ•ŠλŠ”λ‹€.

memoλŠ” 만λŠ₯이 μ•„λ‹ˆλ‹€

μ»΄ν¬λ„ŒνŠΈλ₯Ό memo둜 κ°μŒŒμŒμ—λ„ λΆˆκ΅¬ν•˜κ³ , λ¦¬λ Œλ”λ§λ˜λŠ” λͺ‡ κ°€μ§€ 사둀가 μžˆλ‹€.

  1. propsκ°€ λ³€κ²½λ˜μ—ˆμ„ λ•Œ

CounterButton μ»΄ν¬λ„ŒνŠΈλŠ” count μƒνƒœκ°€ λ³€κ²½λ˜λ©΄ λ¦¬λ Œλ”λ§λœλ‹€. onClick ν•¨μˆ˜κ°€ λ³€κ²½λ˜μ—ˆμ„ λ•Œμ—λ„ λ§ˆμ°¬κ°€μ§€μ΄λ‹€. λ‹Ήμ—°ν•œ κ²ƒμ²˜λŸΌ λ³΄μ΄μ§€λ§Œ μ΄λŠ” μ˜λ„λ˜μ§€ μ•Šμ€ λ™μž‘μ„ λ°œμƒμ‹œν‚¬ 수 μžˆλ‹€.

ReactλŠ” 얕은 비ꡐλ₯Ό 톡해 propsλ₯Ό λΉ„κ΅ν•œλ‹€. 얕은 λΉ„κ΅λ‘œ κ°μ²΄λ‚˜ λ°°μ—΄, ν•¨μˆ˜λ₯Ό λΉ„κ΅ν•˜λ©΄, μ΄μ „μ˜ κ°’κ³Ό λ™μΌν•˜λ”λΌλ„ μ°Έμ‘°κ°€ λ™μΌν•œμ§€μ— λŒ€ν•œ μ—¬λΆ€λ₯Ό λ”°μ§„λ‹€. κ·ΈλŸ¬λ―€λ‘œ μƒμœ„ μ»΄ν¬λ„ŒνŠΈμ—μ„œ λ Œλ”λ§ν•  λ•Œλ§ˆλ‹€ 객체, λ°°μ—΄, ν•¨μˆ˜λ₯Ό λ‹€μ‹œ μƒμ„±ν•œλ‹€λ©΄ memo된 μ»΄ν¬λ„ŒνŠΈ λ˜ν•œ propsκ°€ λ³€κ²½λœ κ²ƒμœΌλ‘œ κ°„μ£Όν•΄ λ¦¬λ Œλ”λ§μ„ λ°œμƒμ‹œν‚¨λ‹€.

이λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ useMemo, useCallback을 μ‚¬μš©ν•˜κ±°λ‚˜, 이후 μ„€λͺ…ν•  arePropsEqual νŒŒλΌλ―Έν„°λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

  1. μ»΄ν¬λ„ŒνŠΈ λ‚΄λΆ€μ˜ μƒνƒœκ°€ λ³€κ²½λ˜μ—ˆμ„ λ•Œ

  2. arePropsEqual 값이 false일 λ•Œ

memo HOC(κ³ μ°¨ μ»΄ν¬λ„ŒνŠΈ)μ—λŠ” 두 번째 인자둜 arePropsEqual νŒŒλΌλ―Έν„°λ₯Ό μΆ”κ°€ν•  수 μžˆλ‹€.

μœ„ 예제의 arePropsEqual ν•¨μˆ˜λŠ” points 객체의 값이 λ³€κ²½λ˜μ—ˆλŠ”μ§€λ₯Ό 확인해, λ³€κ²½λ˜μ§€ μ•Šμ•˜λ‹€λ©΄ true, λ³€κ²½λ˜μ—ˆμœΌλ©΄ falseλ₯Ό λ°˜ν™˜ν•œλ‹€. μ°Έμ‘°κ°€ μ•„λ‹Œ 값을 λΉ„κ΅ν•˜κΈ° λ•Œλ¬Έμ— pointsκ°€ λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈμ—μ„œ μž¬μƒμ„±λ˜μ–΄ μ°Έμ‘°κ°€ λ³€κ²½λ˜μ–΄λ„, 값이 λ³€ν•˜μ§€ μ•Šμ•˜λ‹€λ©΄ Chart μ»΄ν¬λ„ŒνŠΈλŠ” λ¦¬λ Œλ”λ§λ˜μ§€ μ•ŠλŠ”λ‹€.

ν•˜μ§€λ§Œ 이 방법 λ˜ν•œ 만λŠ₯은 μ•„λ‹ˆλ‹€. React 곡식 λ¬Έμ„œμ—μ„œλŠ” arePropsEqual μ‚¬μš© μ‹œ λͺ¨λ“  propsλ₯Ό 비ꡐ해야 ν•˜λ©°, prop의 데이터 ꡬ쑰 κΉŠμ΄κ°€ μ œν•œλ˜μ–΄ μžˆμ§€ μ•Šλ‹€λ©΄ κΉŠμ€ 비ꡐλ₯Ό μˆ˜ν–‰ν•˜μ§€ 말라고 κΆŒκ³ ν•˜κ³  μžˆλ‹€. (곡식 λ¬Έμ„œ)

  1. μ»΄ν¬λ„ŒνŠΈ λ‚΄λΆ€μ—μ„œ Contextλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμ„ λ•Œ

μœ„ μ˜ˆμ œμ—μ„œ globalContext의 count μƒνƒœκ°€ λ³€κ²½λœλ‹€λ©΄ CounterButton이 λ¦¬λ Œλ”λ§λœλ‹€. μ—¬κΈ°μ„œ μ£Όμ˜ν•  점은 globalContext에 λ‹€λ₯Έ μƒνƒœκ°€ μ‘΄μž¬ν•˜κ³ , 이 μƒνƒœκ°€ λ³€κ²½λœλ‹€λ©΄ CounterButtonμ—μ„œ κ·Έ μƒνƒœλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμ§€ μ•ŠμŒμ—λ„ λ¦¬λ Œλ”λ§λœλ‹€λŠ” 것이닀.

이λ₯Ό λ°©μ§€ν•˜λŠ” 방법은 useContext μ‚¬μš©λΆ€λ₯Ό λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈλ‘œ μ΄λ™μ‹œμΌœ, countλ₯Ό props둜 μ „λ‹¬ν•˜λŠ” 것이닀.

useMemo

λ¦¬λ Œλ”λ§ 간에 계산 κ²°κ³Όλ₯Ό μΊμ‹±ν•œλ‹€. - React 곡식 λ¬Έμ„œ

μœ„μ˜ μ˜ˆμ œμ—μ„œ Chartκ°€ λ¦¬λ Œλ”λ§ 될 λ•Œλ§ˆλ‹€ pointsλŠ” λ‹€μ‹œ κ³„μ‚°λœλ‹€. calculatePointsκ°€ 무거운 둜직일 λ•Œ, λΆˆν•„μš”ν•œ μž¬κ³„μ‚°μ„ 막기 μœ„ν•΄ useMemoλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. memorizedPointsλŠ” μ˜μ‘΄μ„± 배열에 ν¬ν•¨λœ dataλ₯Ό Object.is(얕은 비ꡐ)둜 비ꡐ해 λ³€ν™”λ₯Ό κ°μ§€ν•˜κ³ , dataκ°€ λ³€κ²½λ˜μ—ˆμ„ λ•Œμ— ν•œν•΄ 캐싱을 λ¬΄νš¨ν™”ν•΄ 계산을 μ‹œν–‰ν•œλ‹€.

memo와 ν•¨κ»˜ μ‚¬μš©ν•˜κΈ°

memoλŠ” 만λŠ₯이 μ•„λ‹ˆλ‹€ μ„Ήμ…˜μ—μ„œ μ„€λͺ…ν–ˆλ“―이, memo둜 감싼 μ»΄ν¬λ„ŒνŠΈκ°€ κ°μ²΄λ‚˜ 배열인 prop을 ν¬ν•¨ν•˜κ³  μžˆμ„ λ•Œ μ°Έμ‘°κ°€ λ³€κ²½λ˜λ©΄ λ¦¬λ Œλ”λ§μ΄ λ°œμƒν•œλ‹€.

μœ„ 예제의 pointsλ₯Ό prop으둜 λ„˜κ²¨μ€„ 경우, Chartκ°€ λ¦¬λ Œλ”λ§ 될 λ•Œλ§ˆλ‹€ points의 μ°Έμ‘°κ°€ λ³€κ²½λ˜κ³ , 값이 λ³€κ²½λ˜μ§€ μ•Šμ•˜μŒμ—λ„ ChartInner에 연쇄적인 λ¦¬λ Œλ”λ§μ΄ λ°œμƒν•œλ‹€. λ°˜λ©΄μ— memorizedPointsλ₯Ό λ„˜κ²¨μ€€λ‹€λ©΄ dataκ°€ λ³€κ²½λ˜μ§€ μ•ŠλŠ” ν•œ λ™μΌν•œ μ°Έμ‘°λ₯Ό κ°–κΈ° λ•Œλ¬Έμ— λΆˆν•„μš”ν•œ λ¦¬λ Œλ”λ§μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.

μ£Όμ˜μ‚¬ν•­

  • useMemoλŠ” Strict Modeμ—μ„œ 두 번 ν˜ΈμΆœλœλ‹€.

  • memo와 λ§ˆμ°¬κ°€μ§€λ‘œ 얕은 λΉ„κ΅λ‘œ μ˜μ‘΄μ„± 배열을 λΉ„κ΅ν•˜κΈ° λ•Œλ¬Έμ—, 객체 등을 μ˜μ‘΄μ„± 배열에 넣을 λ•Œ μ •μƒμ μœΌλ‘œ λ©”λͺ¨μ΄μ œμ΄μ…˜ λ˜μ–΄μžˆλŠ”μ§€ 확인해야 ν•œλ‹€.

  • μ˜μ‘΄μ„± 배열을 μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄ μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λ Œλ”λ§λ  λ•Œλ§ˆλ‹€ λ‹€μ‹œ ν˜ΈμΆœλœλ‹€.

useCallback

λ¦¬λ Œλ”λ§ 간에 ν•¨μˆ˜ μ •μ˜λ₯Ό μΊμ‹±ν•œλ‹€. - React 곡식 λ¬Έμ„œ

useMemoκ°€ λ³€μˆ˜λ₯Ό μΊμ‹±ν•œλ‹€λ©΄, useCallback은 ν•¨μˆ˜λ₯Ό μΊμ‹±ν•œλ‹€.

μœ„ μ˜ˆμ œμ—μ„œ 두 ν•¨μˆ˜μ˜ μž‘λ™μ€ λ™μΌν•˜λ‹€. ν•˜μ§€λ§Œ ν•¨μˆ˜λ₯Ό 캐싱할 λ•ŒλŠ” ν•¨μˆ˜μš©μœΌλ‘œ μ œκ³΅λ˜λŠ” useCallback을 μ‚¬μš©ν•˜λŠ” 것이 가독성 λ©΄μ—μ„œ μ’‹λ‹€.

useMemo와 λ™μΌν•˜κ²Œ memo둜 감싸진 μ»΄ν¬λ„ŒνŠΈμ˜ λΆˆν•„μš”ν•œ λ¦¬λ Œλ”λ§μ„ λ°©μ§€ν•˜λŠ” 데 μ‚¬μš©λ  수 있으며, μ˜μ‘΄μ„± λ°°μ—΄μ˜ 얕은 비ꡐλ₯Ό μ£Όμ˜ν•΄μ•Ό ν•œλ‹€.

μ „λΆ€ λ©”λͺ¨ν•΄μ•Ό ν• κΉŒ?

memo, useMemo, useCallback에 λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜λ‹€. 이 μ΅œμ ν™” 기법듀은 μ–Έμ œ μ‚¬μš©ν•˜λŠ” 것이 μ’‹μ„κΉŒ? λ Œλ”λ§μ΄ 자주 λ°œμƒν•˜λŠ” μ»΄ν¬λ„ŒνŠΈ? 계산 둜직이 λ³΅μž‘ν•œ μ»΄ν¬λ„ŒνŠΈ? νŒλ‹¨ν•˜κΈ° μ–΄λ €μš°λ‹ˆ μ „λΆ€ λ‹€?

λ©”λͺ¨μ΄μ œμ΄μ…˜μ˜ 기쀀에 λŒ€ν•΄μ„œλŠ” μ—¬λŸ¬ 의견이 μ‘΄μž¬ν•˜κ³ , μ–΄λ–€ 것이 μ„£λΆˆλ¦¬ 쒋닀라고 λ§ν•˜κΈ° μ–΄λ €μš΄ μ£Όμ œμ΄κΈ°λ„ ν•˜λ‹€. React νŒ€μ—μ„œλŠ” λ©”λͺ¨μ΄μ œμ΄μ…˜ λ˜ν•œ λΉ„μš©μ΄κΈ° λ•Œλ¬Έμ—, λΆˆν•„μš”ν•œ λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ λŒ€μ²΄ν•˜λŠ” 방식듀을 μ œμ•ˆν•œλ‹€.

λͺ‡ κ°€μ§€ 원칙을 λ”°λ₯΄λ©΄ λ§Žμ€ λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ λΆˆν•„μš”ν•˜κ²Œ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.

  1. μ»΄ν¬λ„ŒνŠΈκ°€ λ‹€λ₯Έ μ»΄ν¬λ„ŒνŠΈλ₯Ό μ‹œκ°μ μœΌλ‘œ 감싸고 μžˆλ‹€λ©΄ JSXλ₯Ό μžμ‹μœΌλ‘œ λ°›κ²Œ ν•˜μ„Έμš”. κ°μ‹ΈλŠ” μ»΄ν¬λ„ŒνŠΈκ°€ μžμ‹ μ˜ μƒνƒœλ₯Ό μ—…λ°μ΄νŠΈν•˜λ©΄, ReactλŠ” μžμ‹λ“€μ€ λ¦¬λ Œλ”λ§ν•  ν•„μš”κ°€ μ—†λ‹€λŠ” 것을 μ•Œκ²Œ λ©λ‹ˆλ‹€.

  2. κ°€λŠ₯ν•œ ν•œ 둜컬 μƒνƒœλ₯Ό μ„ ν˜Έν•˜κ³ , μ»΄ν¬λ„ŒνŠΈ κ°„ μƒνƒœ 곡유λ₯Ό ν•„μš” μ΄μƒμœΌλ‘œ ν•˜μ§€ λ§ˆμ„Έμš”. νΌμ΄λ‚˜ ν•­λͺ©μ΄ ν˜Έλ²„λ˜μ—ˆλŠ”μ§€μ™€ 같은 μΌμ‹œμ μΈ μƒνƒœλ₯Ό 트리의 μƒλ‹¨μ΄λ‚˜ μ „μ—­ μƒνƒœ λΌμ΄λΈŒλŸ¬λ¦¬μ— μœ μ§€ν•˜μ§€ λ§ˆμ„Έμš”.

  3. λ Œλ”λ§ λ‘œμ§μ„ μˆœμˆ˜ν•˜κ²Œ μœ μ§€ν•˜μ„Έμš”. μ»΄ν¬λ„ŒνŠΈλ₯Ό λ¦¬λ Œλ”λ§ν•˜λŠ” 것이 문제λ₯Ό μΌμœΌν‚€κ±°λ‚˜ λˆˆμ— λ„λŠ” μ‹œκ°μ μΈ ν˜•μ²΄λ₯Ό μƒμ„±ν•œλ‹€λ©΄, 그것은 μ»΄ν¬λ„ŒνŠΈμ˜ λ²„κ·Έμž…λ‹ˆλ‹€! λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ μΆ”κ°€ν•˜λŠ” λŒ€μ‹  버그λ₯Ό ν•΄κ²°ν•˜μ„Έμš”.

  4. μƒνƒœλ₯Ό μ—…λ°μ΄νŠΈν•˜λŠ” λΆˆν•„μš”ν•œ Effectsλ₯Ό ν”Όν•˜μ„Έμš”. React μ•±μ—μ„œ λŒ€λΆ€λΆ„μ˜ μ„±λŠ₯ λ¬Έμ œλŠ” Effectsλ‘œλΆ€ν„° λ°œμƒν•œ μ—°μ†λœ μ—…λ°μ΄νŠΈκ°€ μ»΄ν¬λ„ŒνŠΈλ₯Ό κ³„μ†ν•΄μ„œ λ Œλ”λ§ν•˜λŠ” 것이 μ›μΈμž…λ‹ˆλ‹€.

  5. Effectsμ—μ„œ λΆˆν•„μš”ν•œ μ˜μ‘΄μ„±μ„ μ œκ±°ν•˜μ„Έμš”. 예λ₯Ό λ“€μ–΄, λ©”λͺ¨μ΄μ œμ΄μ…˜ λŒ€μ‹  κ°μ²΄λ‚˜ ν•¨μˆ˜λ₯Ό Effect μ•ˆμ΄λ‚˜ μ»΄ν¬λ„ŒνŠΈ μ™ΈλΆ€λ‘œ μ΄λ™μ‹œν‚€λŠ” 것이 더 κ°„λ‹¨ν•œ κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€.

- React 곡식 λ¬Έμ„œ

λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ λŒ€μ²΄ν•  수 μžˆλŠ” 방법에 λŒ€ν•΄ μ„€λͺ…ν•œ λ‹€λ₯Έ 쒋은 글도 μ²¨λΆ€ν•œλ‹€.

μ°Έκ³  λ¬Έμ„œ

Last updated