React는 Virtual Dom! Svelte는!?

허재원·2023년 2월 18일
0
post-custom-banner

브라우저 렌더링 과정과 Virtual DOM

브라우저 렌더링 과정

크롬이나 사파리, 파이어폭스 같은 것들을 브라우저라고 한다. 페이지의 요소들과 그 구조를 body 태그 안에 header, main, footer, nav 나 ul 아에 묶인 li 등 마크업으로 작성하여 HTML 문서를 클라이언트가 웹 페이지에 접속할 때 쓰는 브라우저에 보낸다.

그러면 브라우저가 HTML 문서를 보고 작성된 요소들로 DOM(Document Object Model) 트리를 구축하고, DOM의 구성요소들은 기본적으로 노드이다. 즉, DOM은 HTML이란 코드로 설계된 웹페이지가 브라우저 안에서 화면에 나타나고 이벤트에 반응하고 값을 입력받는 등 기능들을 수행할 객체들로 실체화된 형태라고 보면 된다. 그리고 필요에 따라 자바스크립트로 노드를 통해 DOM을 조작할 수 있다.
자바스크립트 요소는 아니고 DOM은 API를 가지고 있기 때문에 DOM이 특정 언어에 종속되어 있는 것이 아닌 라이브러리만 갖춰진다면 조작할 수 있다.

CSSCSS Object Model, CSSOM 트리로 구축된다. 브라우저는 DOM 트리와 CSSOM 트리를 융합하여 렌더 트리를 구축한다. 그리고 나서 viewport를 기반으로 렌더 트리의 각 노드가 가지는 정확한 위치와 크기를 계산하여 배치한다. 마지막으로 계산한 위치/크기를 기반으로 각 요소를 화면에 그리는 과정으로 거치면서 우리가 보는 화면들을 만들어 낸다.

Virtual DOM이 나온 이유

브라우저가 HTML을 통해 구축한 것이 DOM이라고 앞서 말한 것처럼 중간에 자바스크립트로 이 DOM을 조작했을때 하나부터 다시 배치하고 그리게 되면 컴퓨터에 부담도 되고 속도도 느리게 된다. 그래서 리액트의 Virtual DOM이 나왔다. Virtual DOM은 DOM의 구조만 간결히 흉내낸 자바스크립트 객체라고 할 수 있다. Virtual DOM을 쓴다는 것은 앞에서 구축된 DOM을 스냅샷으로 만들어 DOM에 조작이 가해지는 경우 먼저 Virtual DOM에서 변경이 일어나고 이전 스냅샷과 비교하여 수정이 필요한 DOM 엘리먼트 목록을 뽑아(diffing) 변경된 부분만 실제 DOM에 적용시켜 딱 필요한 부분만 조작한다. 이를 재조정(Reconciliation) 과정이라고 한다. React가 빠르게 화면을 조작할 수 있는 이유이지만 Virtual DOM 때문에 빠르다고 하는 것은 정확한 표현은 아니다. 그 이유는 Svelte를 통해 알아보자.

Svelte

Svelte에도 Virtual DOM이 있나요?

No virtual DOM
Svelte compiles your code to tiny, framework-less vanillaJS - your app starts fast and stays fast

Svelte는 위에서 언급한 Virtual DOM을 안쓰기 때문에 더 빠르다고 한다. 결국 React도 일부 DOM만 변경시키기 위해서 Virtual DOM이라는 과정이 추가된 것인데 Svelte 프레임워크는 이 Virtual DOM 과정까지 빼서 더 빠르게 효율적으로 DOM을 조작한다고 할 수 있다.

Svelte와 React 차이

React나 Vue는 라이브러리나 프레임워크 형태이고, Svelte는 정확히는 컴파일러라는데 차이가 있다.

React로 만든 사이트들은 React의 기능들을 담은 자바스크립트 파일들을 사용해서 동작하는데, React 전용 코드를 브라우저가 Virtual DOM으로 해석해서 메모리에서 먼저 구현한 다음 최종적으로 실제 DOM에 적용하는 과정은 사이트가 실행되는 시점 즉, 런타임에서 일어난다. Virtual DOM은 이 런타임이란 제약 조건 하에서 브라우저에 로드된 라이브러리로서 DOM에 가해지는 변화들을 최소한의 변경으로 구현할 방법을 찾는 방식이다.

그에 반해 Svelte는 그 과정을 사이트가 배포되기 전에 미리 다 해두도록 한 것이다. 이를 컴파일이라 하고, Svelte 형식에 맞게 코드를 작성하고 빌드하면 Svelte는 사이트에서 실제로 일어날 일들, 어떤 이벤트가 들어오면 어떤 변화가 일어날지들을 컴팩한 자바스크립트 파일로 컴파일해서 내놓기 때문에 용량 면에서도 더 가볍고 DOM의 조작도 더 빠르다.

하지만 Svelte가 React에 비해 아직 기능이나 커뮤니티가 덜 쌓인 부분들이 있고, 코드를 미리 컴파일해서 내보내야 하기 때문에 특정 형태의 사이트에서는 한계가 될 수 있다.

Svelte 사용해보기

글이 너무 길었는데 최신근에 나온 SvelteKit을 이용하여 가볍게 프로젝트를 진행해보자.

프로젝트 셋팅

npm create svelte@lastest movie-app
cd movie-app
npm install
npm run dev

파일 시스템 기반 라우터

SvelteKit도 Next.js처럼 filesystem-based router이다. 위 사진처럼 routes 폴더를 기반으로 파일 시스템 라우팅을 할 수 있다.

서버에서 클라이언트 데이터 전송

서버에서 데이터를 가져와서 데이터를 페이지에 보여주기 위해서는 해당 폴더에 +page.js+page.server.js를 생성하여 작성하면 된다. 그러면 +page.svelte 파일 로드시 같이 있는 js 파일도 실행이 된다.
그리고 +page.server.js로 파일을 생성하면 서버에서만 실행되기 때문에 SSR로 동작하게 된다.

export async function load({ fetch }) {
  const res = await fetch(`https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}&language=en-US&page=1`)

  if (res.ok) {
    const data = await res.json();

    return data;
  }
}

서버로부터 받은 데이터 렌더링

<script>
  export let data; // 위 함수에서 return으로 받은 데이터
  
  import PopularMovies from '../components/PopularMoviews.svelte';
</script>

<section>
  <PopularMovies popular={data.results}/>
</section>

<script> 태그 안에 +page.server.js에서 받아온 데이터를 export let data를 작성하여 사용할 수 있고, 그 외 컴포넌트도 import할 수 있다.

PopularMovies 컴포넌트 생성

<script>
  import MovieCard from "./MovieCard.svelte";

  export let popular;
</script>

<h3>Popular Moviews</h3>
<div class="popular-movies">
  {#each popular as movie}
    <MovieCard {movie} />
  {/each}
</div>

<style>
  h3 {
    padding: 0 1rem;
  }

  .popular-movies {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    grid-column-gap: 1rem;
    grid-row-gap: 1rem;
  }
</style>
{#each popular as movie}
  <MovieCard {movie} />
{/each}

그리고 React를 사용하면 컴포넌트를 보통 JavaScript의 map을 사용하여 반복되는 컴포넌트를 렌더링할 수 있지만 아래 코드처럼 좀 더 직관적이고 가독성 있는 코드를 작성하여 컴포넌트를 반복하여 렌더링할 수 있다. 이러한 부분인 예전 JSP를 배우거나 템플릿 엔진과 비슷하다는 느낌을 많이 받았다.

결과❗️

유행하는 영화 목록을 보여주는 페이지 완성! 진짜 코드가 직관적이고 또 사용하기 편리하다는 느낌을 많이 받았다..!

post-custom-banner

0개의 댓글