[ Essay - Technology, Essay - Intuition ] Chat GTP시대의 도래와 생각하는 방식에 대해

이미지
올해도 드디어 끝이 보이는 듯 싶다. 최근에 회사의 망년회를 끝내고 이래저래 회식이 늘어나는 듯 하다. 지금 시점에서는 개인적인 스케쥴도 마무리 되었기 때문에 이제는 여유롭게 연말을 즐기며 올해를 마무리 하려고 한다. 비교적 최근에 이사한 곳 근처의 스타벅스가 대학 병원 안에 있고 근처에 공원이 있어서 그런지 개를 대리고 산책하는 노인이나  아이를 동반한 가족이 눈에 띄게 보인다. 꽤나 좋은 곳으로 이사한듯 하다. 개인적으로는 올해 드디어 미루고 미루었던 이직을 하였고  그 이후에 비약적인 성장을 이루었으니  분명 안좋은 일도 있었지만 만족할 수 있는 해를 보내지 않았나 싶다. 내가 도달하려고 하는 곳으로 가려면 아직 갈길이 멀지만  궤도에 오른 것만으로도 큰 성과라면 큰 성과 일 것 이다. 어쨋든 이직하고 많은 일들을 맡게 되었는데 그 과정에서 나는 의도적으로 Chat GTP를 활용하고자 하였고 몇 가지 직감을 얻게 되었는데  이 중 한 가지를 글로 작성하려고 한다. 따라서 올해의 마무리 글은 Chat GTP에 대한 이야기로 마무리 하려고 한다. 서론 불과 약 10년전 IT업계는 원하던 원치 않던간에  한번의 큰 패러다임의 변화를 맞이해야만 했다 바로 아이폰의 등장에 따른 스마트폰의 시대의 도래와  이에 따른 IT업계의 패러다임 변화가 그것이다. 내 기억으로는 아주 격변의 시대였던 걸로 기억하는데 왜냐하면 게임은 물론이고 웹과 백신을 비롯한 모든 솔루션의 변화가 이루어졌다. 이 뿐만 아니라 가볍고 한손의 들어오는 이 디바이스는  그 당시에는 조금 비싸다는 인식이 있었지만  감추려고 해도 감출 수 없는 뛰어난 유용성으로 회의론을 금세 종식시켰고 이에 대한 결과로 어린아이 부터 노인 까지 작은 컴퓨터를 가지게 되었고 이는 당연하게도 IT업계의 전체적인 호황을 가져다주었다.  그리고 질서는 다시 한번 재정렬되었다. 이러한 패러다임의 변화의 증거로 언어 또한 변하게 되었는데...

[ React ] React에 대해 : 리렌더링과 memo 메소드



서론

React는 기본적으로 언제 리렌더링 될까?

React에 대해 조금 지식이 있다면 잘 알다시피
아래와 같이 크게 2가지로 나눌 수 있다.

첫 번째, 컴포넌트의 상태(state), 프로퍼티(props) 변경되었을 때
두 번째, 상위 부모 컴포넌트가 변경되었을 때   

첫 번째의 경우는 React의 가상 DOM(VDOM)에서
이전 VDOM과 비교해서 변경 된 곳만 실제 DOM에
업데이트 해주기 때문에 이 경우 신경 쓰지 않아도 된다.

하지만,
이 중 두 번째의 경우가 가장 문제일 수 있는데 
부모 컴포넌트가 어떤 값이던 간에 바뀐다면
그 하위의 자식 컴포넌트 모두가 리렌더링 대상이 되기 때문이다

즉, 어떤 한 하위 자식 컴포넌트의 값이 변했을 때,
그와 관련 없는 또 다른 자식 컴포넌트 까지 렌더링 대상이 된다는 것 이다.

그렇기 때문에 
여기서 우리는 최적화에 대한 문제에 직면하게 된다.

먼저 두 번째에 경우에 대해 이야기하기 전에 
React의 이해를 돕기 위해 첫 번째의 경우 부터 이야기를 나누어보자.  

첫 번째: 상태와 프로퍼티가 변경되었을 때

본론에 들어가기 앞서
먼저 VDOM에 대해 이야기를 해보자.

사실 React의 매력은 이 VDOM에 있다고 볼 수 있다.

왜냐하면 일반적인 DOM에서 내부 구성 변경되면
UI를 새로 다시 그리기 때문에 
기본적으로 애플리케이션의 성능이 그렇게 썩 좋다고 보기는 힘들다. 

하지만 이와 다르게 React의 VDOM은 
업데이트 된 부분만 수정하기 때문에
일반 DOM을 활용한 시스템보다는 
퍼포먼스 측면에서 유리하다고 할 수 있다.

이렇게 실제 DOM과 가상 VDOM을 동기하는 과정을 
reconciliation(조정)이라고 하는 것 같지만
실제로는 diffing이라는 단어를 자주 사용하는 것 같다.

VDOM[1] 에 대한 내용과 Reconciliation[2] 에 대해서는 
공식 도큐먼트에서 확인하기를 바란다.

VDOM에 대한 이야기도 조금 했으니 
이제 본론으로 넘어가 보자.

여기서 상태(State)와 프로퍼티(props)가 무엇을 말하는 것일까?

React에 익숙하지 않다면, 다소 이해 하기 힘들 수 있다.

나는 이 포스트 바로 전에 React를 소개하는 글을 포스팅 했는데,
이 포스팅에는 버튼을 눌렀을 때, 
카운트 횟수를 화면에 보여주는 앱이 있다.

class App extends React.Component {

  state = { display: true };
  delete = () => {
    this.setState({ display: false });
  };

  render() {
    let comp;
    if (this.state.display) {
      comp = <Hello />;
    }

    return (
      <div>
        <div>
        {comp}
        <button onClick={this.delete}>Hello Component unMount</button>
        </div>

        <Welcome />
      </div>
    );
  }
}

위의 코드에서 상태의 변경은 

  state = { display: true };
  delete = () => {
    this.setState({ display: false });
  };

이 부분이다.

버튼을 누를 때 마다,  
delete 함수가 실행되고 

내부 처리 부분 
즉, setState에 의해 변수 display상태가 변경된다.

위에서 부터 설명에 따르면 
이 부분에서 리렌더링이 일어 

우리의 인식이 같다면 말이다.

다음은 프로퍼티에 대한 이야기이다.

class App extends React.Component {    
  render() {    
      return (        
          <NameTextDisplay firstName="kim" secondName="minsu"/>    
      );  
  }
}

const NameTextDisplay = ({firstName, secondName}:props) => {    
  return <p>`${firstName} ${secondName}`</p>;
};

위의 코드에서 프로퍼티에 대한 부분은
NameTextDisplay 컴포넌트의 내부 속성인 firstName와 secondName를 말한다.

({firstName, secondName}:props)

실제 자식 컴포넌트로 넘길 때
props 변수 안에 넣어서 보내기 때문에 위와 같은 코드가 필요하다.

단순히 props만 받는다면
props.firstName
props.secondName
위와 같은 방식으로 접근 할 수 있다.

물론 TypeScript까지 활용해서 
타입(변수형)까지 설정해준다면 좀 더 완벽한 코드가 될 것이다.

TypeScript까지 이야기 하면 
이 포스팅의 목적과 벗어나기 때문에 여기까지 하자.

어쨋든
이 코드는 처음 렌더링 될때 빼고는 
값의 변경이 이루어지지 않기 때문에

리렌더링은 일어나지 않지만, 
state로 변수를 넣어주고 
이를 변경하는 코드를 추가한다면 리렌더링이 일어날 것 이다.

위에서 언급했듯이
이 부분은 React의 VDOM에서 자동적으로 처리해주기 때문에 
크게 신경 쓸 필요는 없을 것이다.

두 번째: 상위 부모 컴포넌트가 변경되었을 때 그리고 문제점

이제 본격적인 내용으로 들어가보자.

문제에 대해서는 서론에서 이야기를 했기 때문에 

좀 더 깊은 이해에 다가가기 위해 
간단한 예를 통해 이야기를 나누어보자.

아래와 같이 현재 시간을 표시하는 컴포넌트를 
대략적으로 설계했다고 가정해보자.


여기서 Clock Component는 부모 컴포넌트가 되며,
하위 DateDisplay와 TimeDisplay는 각각 자식 컴포넌트가 된다.

여기서 DateDisplay는 년월일을 보여주며, 
TimeDisplay는 시분초를 보여주는 컴포넌트라 가정해보자.

내부 로직에 대해서는 잠시 머리속에 지워버리고 결과값에만 집중해보자.


우리가 시계에 대한 정의가 일치한다면
DateDisplay의 값은 비교적 그대로 인데 비해,
시간은 초 단위로 계속 바뀌기 때문에 TimeDisplay는 계속적으로 변하게 될 것이다.

문제는 TimeDisplay의 값이 변하면서 리렌더링 되는 것은 상관없지만,
불필요한 DateDisplay 까지 리렌더링 대상이 된다는 것이다.

따라서 이런 최적화 문제를 해결하기 위해서 
값이 변하지 않았을 경우, DateDisplay가 리렌더링 되지 않도록 하는 
솔루션이 우리에게 필요하다는 결론에 도달할 수 있다. 

해결

다행히도 React는 이 문제에 대한 솔루션을 기본적으로 제공해준다.

바로 memo라는 메소드를 통해서 말이다.

사용 방법은 여러가지가 있을 수 있지만
위의 예라면 아래와 같이 해당 컴포넌트를 감싸주면 해결이 된다.

export default React.memo(DateDisplay);

이렇게 함으로써 TimeDisplay는 계속해서 값이 변하게 되므로
리렌더링이 이루어질 것이고,
DateDisplay는 날짜가 변하게 되면 값이 변하기 때문에
그 때만 값이 리렌더링 될 것이다.

간단한 예이기 때문에 
코드로 살펴보자.

마치며

물론 위의 예제는 매우 간단한 예제로
사실 굳이 memo 메소드를 사용한다고 해도 성능에 큰 차이는 없을 것이다.

하지만,
우리가 개발해야하는 대량의 데이터를 처리해야하는
사용자가 많은 엔터프라이즈 급 시스템이라면 이야기가 다를 것 이다.

경우에 따라서 고작 몇 단어에 불과한 
이 메소드를 추가하지 않았기 때문에 성능에 큰 문제를 야기할 수 있기 때문이다.

따라서 최적화 단계에 들어가 있는 React를 사용하고 있는 시스템이라면
이 memo 함수를 어디에 적절하게 사용하면 
성능을 향상 시킬 수 있는지에 대해 생각해보는 것이 좋을 지도 모른다.




이 블로그의 인기 게시물

[ Web ] 웹 애플리케이션 아키텍처 (Web Application Architecture)

[ Web ] 서버 사이드(Sever Side) ? 클라이언트 사이드(Client Side)? 1 [서론, 클라이언트 사이드(Client Side)]

[ Web ] 웹 애플리케이션 서버 아키텍처의 정의 및 유형 ( Define and Types of Web Application Server Architecture )