React-lite 걷어낸 이야기

React-lite는 웹 브라우저 환경에서 React를 실행하는 데 필요없는 코드를 제거해서 경량화 한 버전의 React다. React v.0.14.4까지(2016.01 기준) 지원하고 간편하게 설정하고 제거할 수 있어 회사에서 하고 있던 프로젝트에 간단하게 적용을 테스트해봤다. 효과는 놀라운데 react-lite를 적용한 제품 코드를 Webpack으로 빌드했더니 사이즈가 무려 반으로 줄었다.

React addons를 지원하지 않아서 ReactTestUtils를 사용할 수 없다는 단점이 있지만 WebPack을 이용하면 동적으로 설정을 넣고 빼기가 쉬워서 테스트 환경에서는 정식 React를 사용하고, 빌드만 React-lite를 이용하게 설정할 수 있었다. 아래의 설정을 webpack.conf.js에 추가하고 테스트 환경에서는 제거하는 방식이다.

1
2
3
4
5
6
resolve: {
    alias: {
        'react': 'react-lite',
        'react-dom': 'react-lite'
    }
},

신나서 바로 도입을 결정했다. 이 때가 정식 QA 들어가기 전이었기 때문에 시기상으로도 적절했다. 하지만 슬프게도 한 2주 정도 사용하다가 몇 가지 이슈 때문에 다시 오리지널 React로 회귀했다.

 

이벤트 이슈

react-lite가 document.body에 걸려있는 기본 이벤트 실행을 막아버려서 발행 레이어를 닫는 이벤트를 받을 수가 없다. 개발자한테 물어봤더니 React에서 크로스브라우징 이벤트를 처리하는 코드의 양이 많아서 경량화를 위해서 제거하는 대신 사이드 이펙트가 없도록 React 외부로 나가는 이벤트를 막았다고 한다. 이는 React를 다른 UI 라이브러리와 혼용해서 사용할 경우 심각한 문제를 만들 수 있다.

이슈 제기를 했고, 지금은 새로운 버전이 나오면서 이 문제는 해결이 되었다.

https://github.com/Lucifier129/react-lite/issues/27

 

IE 11 렌더링 오류

IE 11에서 간혹 컴포넌트 렌더링 여부를 판단하는 규칙이 React와 달라서 렌더링 해야하는 상황인데도 라이프 사이클 메서드를 호출하지 않고 지나쳐버리는 경우가 있다. React-lite를 걷어내게 만든 결정적인 이유다. 분명히 컴포넌트를 다시 렌더링해야하는 상황인데 생략해버린다. render는 호출하지만 diff 로직을 제대로 못타는 거 같다고 추정만할 뿐 정확한 이유를 찾지 못했다. shouldComponentUpdate로 오버라이딩해보고, forceUpdate도 호출해보고 별 짓을 다 해봤지만 우회할 방법을 찾지 못했다.

프로젝트 일정이 빠듯한 상황에서 내부 코드를 빠삭하게 이해하고 있지 않은 이상 정확한 원인을 찾기가 힘들다고 판단해서 결국 회귀를 결정했다. 200kb가 아쉽지만 스트레스받고 시간 버리느니 그냥 포기하고, 파일 사이즈가 성능에 영향을 미칠정도 수준이면 차라리 webpack의 chunk를 이용해서 파일을 분리할 생각이다.

 

버전 관리 이슈

이벤트 이슈를 확인하다가 react-lite가 React의 일부 코드를 단순히 제거한 게 아니라, 코드의 많은 부분을 수정한 버전이라는 걸 알았다. 새로운 버전의 React가 나와도 바로 적용할 수 없다. 결국 향후 버전 관리에 문제가 생길 가능성이 높다.