functional component 는 성능 향상에 도움이 될까?

김도연
6 min readSep 14, 2018

--

슈뢰딩거의 고양이(슈레딩거가 아닙니다)

4주간 진행된 슈뢰딩거의 고양이 프로젝트에서 일어난 이슈들을 이야기하는 포스팅입니다. 슈뢰딩거의 고양이는 react native로 제작된 위치기반 랜덤 채팅 서비스를 제공하는 앱입니다. 앱스토어와 플레이스토어에서 다운로드 하실 수 있습니다

코드가 안정화되고 최적화 및 성능향상을 위한 고민을 시작했다. 리액트의 성능향상을 위한 방법은 여러가지가 있다. 개발자들마다 의견도 조금씩 다르고 어떤 이슈는 트위터에서 화끈하고 흥미진진한 토론이 벌어지기도 한다.

트위터 토론 관전은 언제나 재미지다

여러 레퍼런스들이 있지만 몇가지만 간단하게 소개한다.

  • Use functional component(stateless component) or shouldComponentUpdate
  • Use key attribute on list items
  • Bind early and don’t create functions inside render.
  • Don’t update state or dispatch actions in componentWillUpdate
  • Use VirtualizedList, FlatList and SectionList for large data sets.

이중에 개인적으로 궁금하고 확인해보고 싶었던 부분은 functional component(stateless component)를 사용했을 때 성능향상이 있을 것인가였다( ShouldComponentUpdate에 대한 부분은 다음번 포스팅에서 다룰 것이다).

여기서 본론으로 들어가기 전에, 간단히 stateful component와 functional component 에 대해 이야기하고 넘어가자.

stateful component VS functional component

stateful component는 말 그대로 state가 있는 컴포넌트다. lifecycle 함수도 사용할 수 있다. state를 요구하는 한 이런 형식을 사용해야 한다. 간단한 예제를 살펴보자.

stateful component

위 코드를 보면 popcorns란 state를 가지고 그것을 랜더 해주고 있다. state가 불필요하지만 쓰고 있다는 것을, 눈치가 빠르며 똑똑한 당신은 이미 알고 있다(물론 예제코드가 성의없다는 것도 알고..).

그렇다면 functional component는 무엇일까?

functional component

처음 예제코드를 functional component로 바꾸어 보았다. 순수 자바스크립트 함수로만 이루어져있다. 더 짧아지고 간결해져서 보기에 편하다. 그렇다면 컴파일 된 파일은 어떨지 궁금해졌다.

바벨로 컴파일 한 코드를 비교해보자.

stateful component after babel compiled
functional component after babel compiled

위 코드는 stateful component 이고 아래는 functional component 이다. 몇줄 차이가 몇십줄 차이가 되었다. 내용이 늘어난 만큼 파일의 용량 차이도 있을 것이고 첫 마운트시 속도의 차이도 있을 것이라는 생각이 들었다.

컴파일한 코드에서 볼 수 있듯, class를 사용하고 state를 설정하는 것이 성능에서 어떤 차이가 있을 것이라 예상할 수 있었다. 그리고 state를 사용하지 못하는 functional component는 lifecycle함수도 사용할 수 없다. 그래서 가설을 세우고 검증해보기로 했다.

state와 lifecycle이 없으니 불필요한 체크 및 메모리 할당이 없어서 성능 향상이 있을 것이다

이 가설을 검증하기 위해 컴포넌트 하나를 리팩토링해서 성능을 측정해보기로 했다.

슈뢰딩거의 고양이 앱의 채팅창에서 채팅을 그려주는 컴포넌트인 Chat component는 부모 컴포넌트에서 랜더에 필요한 props를 모두 상속받아 사용할 수 있다. 대략적인 구조는 아래와 같다.

슈뢰딩거의 고양이 채팅방 구조

state를 사용하고 있던 기존 Chat component를 functional component로 리팩토링하고 react native debugger를 사용해 퍼포먼스를 측정해 보았다.

Before

After

scripting과 reconciliation 시간이 약 10%정도 감소한 것을 볼 수 있다. 어느 정도 성능향상이 있다는 것을 확인 할 수 있었다. Chat component처럼 단순히 그려주는 컴포넌트들이 많다면 더 큰 성능향상을 기대할 수 있을 것 같다.

가설을 검증하는 과정에서 알게된 새로운 점들

  • stateful 에서 functional 로 리팩토링하는 과정에서 코드가 간결해지며 이해하기 쉬워졌다.
  • this가 없어졌으니 bind할 필요도 없어졌다.
  • 코드가 짧아지면서 노이즈의 발생 가능성이 줄어들 것이란 예상도 할 수 있었다.
  • container component / presentational component 구성처럼 행동과 표현 로직을 나누는 패턴을 사용할 때 유용하게 사용할 수 있다.

가독성이 높고 이해가 쉬운 간결한 코드로 짤 수 있다는 점은 협업할 때도 유용하게 사용될 것 같다.

--

--

김도연
김도연

No responses yet