라이브러리/프레임워크는 왜 필요한가?
웹 사이트를 만들기 위해선, 굳이 라이브러리나 프레임워크 없이도 구조를 담당하는 HTML, 표현을 담당하는 CSS, 사용자의 행동흐름에 따라서 동작하게끔 하는 Javascript로 만들 수 있습니다.
하지만 요즘의 웹은 옛날처럼 정적으로 웹 페이지가 아니라, 웹 어플리케이션로 사용자와의 상호작용이 매우 자유롭게 이어지고 있습니다.
Javascipt를 예제로 들어보면,
document.querySelector("div");
이것을 jQuery로 나타내면,
$('div')
이런식으로 DOM을 가져옵니다.
하지만, 프로젝트의 규모가 커지고, 정말 다양한 사용자와의 인터렉션을 제공하게 된다면, 그 많은 DOM 요소들을 직접 관리하고, 코드 작성하는 것은 정말 힘든 일입니다.
즉, 웹 개발을 할 때, 귀찮은 DOM 관리 나, 상태 값 업데이트 관리를 최소화 하고, 기능 개발, 사용자 인터페이스(UI)를 구현하는 것에 집중할 수 있도록 하기 위해 여러 라이브러리나 프레임워크가 등장했습니다.
React 소개
리액트의 매뉴얼을 보면 다음과 같은 내용이 있습니다.
We built React to solve one problem: building large applications with data that changes over time. 번역: 우리는 지속해서 데이터가 변화하는 대규모 애플리케이션을 구축하기 위해 React를 만들었습니다
“변화(Mutation)” 는 복잡한 작업입니다. 특정 이벤트가 발생했을 때, 모델에 변화를 일으키고, 변화를 일으킴에 따라 어떤 DOM을 가져와서 어떠한 방식으로 뷰를 업데이트 해줄 지 로직을 정해줘야 합니다. 페이스북은 아래와 같이 이러한 발상을 했다고 합니다.
Mutation을 하지 말자. 그 대신에, 데이터가 바뀌면 그냥 뷰를 날려버리고 새로 만들어버리면 어떨까?
그렇게 하면 정말 간단하겠지만, DOM 기반으로 하는 웹은 계속 새로운 뷰를 만들어버리면 성능적으로 엄청 문제가 생길 것입니다.
그래서 나오게된 것이 “Virtual DOM” 입니다.
Virtual DOM
Virtual DOM은 말 그대로 가상 DOM 입니다. 변화가 일어나면, 실제로 브라우저의 DOM에 적용하는 것이 아니라, 자바스크립트로 이뤄진 가상 DOM에 한 번 렌더링을 하고, 기존의 DOM과 비교를 한 다음에 정말 변화가 필요한 곳에만 업데이트를 해주는 것입니다.
Virtual DOM 을 사용함으로서, 데이터가 바뀌었을 때 더 이상 어떻게 업데이트 할 지 로직을 고려하는게 아니라, 그냥 일단 바뀐 데이터로 일단 그려놓고 비교를 한다음에, 바뀐 부분만 찾아서 바꿔주는 것입니다.
Virtual DOM을 쉽게 이해할 수 있는 velopert님의 동영상이 있습니다.
- React and the Virtual DOM : (https://www.youtube.com/watch?v=muc2ZF0QIO4)
왜 Virtual DOM 인가?
DOM을 조작했을 때,
DOM 변화 —> Render Tree 재생성 (모든 요소들의 스타일이 다시 계산) —> 레이아웃 계산 —> 페인팅
복잡한 SPA(Single Page Application) 에서는 DOM 조작이 많이 발생한다. 그 뜻은 그 변화를 적용하기 위해 브라우저가 많이 연산을 해야한단 소리고, 전체적인 프로세스를 비효율적으로 만듭니다.
예를 들어,
30개의 노드를 하나 하나 수정하면,
30번의 (잠재적인) 레이아웃 재계산과 30번의 (잠재적인) 리렌더링을 초래합니다.
그러나, Virtual DOM을 사용하게 되면,
모든 변화를 하나로 묶어서 딱 한 번 실행합니다.
그렇게 되면, 1번의 레이아웃 재계산과 1번의 리렌더링을 합니다.
따라서, 뷰에 변화가 있다면, 그 변화는 실제 DOM에 적용되기 전에 가상의 DOM에 먼저 적용시키고 그 최종적인 결과를 실제 DOM으로 전달해줍니다. 이로써, 브라우저 내에서 발생하는 연산의 양을 줄이면서 성능이 개선됩니다.
사실 이 과정은 Virtual DOM 없이 변화가 있을 때, 그 변화를 묶어서 DOM fragment에 적용한 다음에 기존 DOM에 적용하면 된다고 합니다.
그러면, Virtual DOM이 해결하려고 하는 것은 무엇이냐?
-
위에 말한 DOM fragment를 관리하는 과정을 수동으로 작업할 필요 없이, 자동화하고 추상화하는 것이다.
-
기존 값 중 어떤 것이 바뀌었고, 어떤 것이 바뀌지 않았는지 계속 파악하기 쉽지 않기 때문에, 이것을 알아내어 해결해줍니다.
-
DOM 관리를 함으로써, 컴포넌트가 DOM 조작 요청을 할 떄, 다른 컴포넌트들과 상호작용을 하지 않아도 되고, 특정 DOM을 조작할 것 이라던지, 이미 조작했다던지에 대한 정보를 공유할 필요가 없다. 즉, 각 변화들의 동기화 작업을 거치지 않으면서도 모든 작업을 하나로 묶어줄 수 있다.
참고 - https://velopert.com/3236
그 외의 React와 관련된 정보
리액트는 정말 자유도가 높은 라이브러리입니다. 예를들어서 라우터, 혹은 상태관리 같은 기능들이 리액트 자체에 내장되어있지도 않고, 공식적인 라이브러리도 없습니다. 하지만 써드파티 라이브러리가 존재합니다.
- 라우터쪽을 보자면, React-router, 그리고 Next.js, After.js 같은 라이브러리들이 있습니다.
- 상태 관리 라이브러리만해도, Redux, MobX, fr(e)actal 같은 라이브러리들이 있습니다.
그리고 리액트 컴포넌트 스타일링을 할 때도 한가지 정해진 방식이 있는게 아니라 수많은 방식으로 할 수 있습니다.
이에 따른 장점은, 여러분들이 가장 맘에드는것을 사용하거나 심지어 직접 만들어서 사용 할 수도 있다는 점이고, 단점은 여러가지를 시도해볼 필요가 있고, 어느 것 하나를 선택하는 게 어려울수 있다는 점 입니다.