React 16 Fiber 아키텍처와 성능 개선

배경

운영 중인 대시보드 프로젝트에서 대량의 데이터를 렌더링할 때 브라우저가 멈추는 문제가 있었다. React 16 베타를 테스트해보다가 정식 릴리즈가 나와 마이그레이션을 진행했다.

Fiber의 핵심 변화

React 15까지는 reconciliation이 동기적으로 실행되어 렌더링이 시작되면 중단할 수 없었다. Fiber는 작업을 청크 단위로 나누고 우선순위를 부여하여 필요시 중단/재개가 가능하다.

// 기존에 문제가 되던 케이스
class DataTable extends React.Component {
  render() {
    return (
      <table>
        {this.props.data.map(item => (
          <tr key={item.id}>
            <td>{item.name}</td>
            <td>{item.value}</td>
          </tr>
        ))}
      </table>
    );
  }
}

500개 이상의 row를 렌더링할 때 React 15에서는 UI가 확연히 버벅였는데, React 16에서는 체감상 개선되었다.

Error Boundary

개인적으로 가장 유용했던 기능은 Error Boundary다. 기존에는 컴포넌트 에러가 전체 앱을 망가뜨렸다.

class ErrorBoundary extends React.Component {
  state = { hasError: false };

  componentDidCatch(error, info) {
    this.setState({ hasError: true });
    // 로깅 서비스 전송
    logErrorToService(error, info);
  }

  render() {
    if (this.state.hasError) {
      return <h2>문제가 발생했습니다.</h2>;
    }
    return this.props.children;
  }
}

마이그레이션 포인트

  • React.PropTypes가 별도 패키지로 분리 (prop-types)
  • 대부분의 케이스에서 코드 변경 없이 동작
  • 번들 사이즈 소폭 증가 (gzip 기준 약 2KB)

운영 환경에 배포 후 별다른 이슈는 없었다. Fiber의 진가는 향후 async rendering이 추가되면 더 드러날 것으로 보인다.