1. Svelte 소개 - 컴파일 방식의 UI 프레임워크

2020. 8. 26. 22:28재주껏 하는 Front-End/Svelte (준비중)

반응형

최근 프런트엔드 프레임워크는 흔히 말하는 3대장인 ReactJS, VueJS, Angular로 3 분할되어있다. 전통적인 웹페이지 개발 방식과 달리 컴포넌트의 개념을 도입해 재사용성과 생산성이 뛰어나고 Virtual DOM을 사용하여 페이지가 동적으로 동작하는 데 있어 강력한 성능을 제공하는 것이 3 대장 프레임워크의 공통적인 장점이다.

 

프론트 엔드 3대장 앵귤러, 리액트, 뷰

 

그런데 최근에 3 대장 프레임워크에 도전하는 녀석이 나타났다. 우리나라에서는 2년 전부터 알려지기 시작했으며 자신이 더 작고, 더 가벼우며, 더 빠르게 반응하는 진정한 반응형 프레임워크라고 주장한다. 개발자로서 이런 말을 들었는데 궁금하지 않을 수가 없어 이 녀석에 대해 좀 더 자세히 알아보고자 블로그에 하나씩 정리하고자 한다. 웹 프레임워크 3 대장의 자리를 넘보는 컴파일러 Svelte에 대해 알아보자.

 

떠오르는 강자 Svelte

 

Svelte는 ReactJS, VueJS, Angular와 같이 자바스크립트로 구성된 UI 프레임워크 중 하나로, 적은 코드와 작은 모듈 크기 그리고 Virtual DOM을 사용하지 않는 특징을 가진 프런트엔드 프레임워크이다.

 

Svelte는 2019년 전 세계 프런트엔드 프레임워크 중 개발자들이 가장 많은 흥미를 갖고 있는 프레임워크로 선정되었으며, 실제 만족도 역시 ReactJS 다음으로 높은 것으로 조사되었다. 아래와 같이 Svelte는 전 세계적으로 3 대장 프레임워크 뒤를 이어 빠르게 성장하고 있는 차세대 프런트엔드 프레임워크라고 요약할 수 있겠다.

 

2019년 프론트엔드 프레임워크 만족도 조사 결과
2019년 프론트엔드 프레임워크 인기도 조사 결과

 

Svelte는 적은 코드양, Virtual DOM을 사용하지 않음, 진정한 반응성 3가지를 대표적인 특징이자 장점으로 내세우고 있다.

 

Svelte의 3가지 특징

 

아래에서 이 3가지 특징에 대해 자세히 알아보자.

 

코드가 매우 적은 Svelte

 

Svelte가 주장하는 첫 번째 장점은 똑같은 결과물을 더 적은 양의 코드로 완성할 수 있다는 것이다. 아래와 같은 덧셈 웹 애플리케이션을 만들어야 한다고 가정해보자.

 

덧셈 어플리케이션 (?)

 

먼저 ReactJS로 만들어보자. 매우 간단한 애플리케이션이지만 많은 코드가 필요하다.

 

import React, { useState } from 'react';

export default () => {
  const [a, setA] = useState(1);
  const [b, setB] = useState(2);

  function handleChangeA(event) {
    setA(+event.target.value);
  }

  function handleChangeB(event) {
    setB(+event.target.value);
  }

  return (
    <div>
      <input type="number" value={a} onChange={handleChangeA}/>
      <input type="number" value={b} onChange={handleChangeB}/>

      <p>{a} + {b} = {a + b}</p>
    </div>
  );
};

 

다음은 VueJS로 만들어보자. ReactJS 보다 코드의 양이 적어 가독성이 좋다.

 

<template>
  <div>
    <input type="number" v-model.number="a">
    <input type="number" v-model.number="b">

    <p>{{a}} + {{b}} = {{a + b}}</p>
  </div>
</template>

<script>
  export default {
    data: function() {
      return {
        a: 1,
        b: 2
      };
    }
  };
</script>

 

마지막으로 Svelte로 만들어보자. 훨씬 적은 코드만으로 동일한 애플리케이션을 만들어 낼 수 있었다. 일반적으로 Svelte가 ReactJS보다 40% 적은 코드로 동일한 결과물을 낼 수 있다. (고 주장한다)

 

<script>
	let a = 1;
	let b = 2;
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {a + b}</p>

 

 

코드의 양이 적어지면 가독성이 좋아 유지 보수하기 쉽고, 모듈의 크기가 줄어들기 때문에 번들링 시 더 적은 용량으로 동일한 애플리케이션을 만들 수 있다. 또한, ReactJS나 VueJS 대비 코드 작성이 자유로워 하나의 컴포넌트에서 더 많은 기능을 구현할 수 있게 되었다.

 

번들링 결과에 대한 크기 비교. Svelte가 압도적으로 작은 것을 볼 수 있다.

 

다만, 실제로 Svelte를 사용해 본 결과 덩치가 커지면 커질수록 코드가 뒤죽박죽 섞일 가능성이 높기 때문에 최소 VueJS의 싱글 파일 컴포넌트 문법과 비슷하게 Template, Script, Style로 나눠진 것과 같이 암묵적인 약속이 필요해 보인다.

 

Virtual DOM을 사용하지 않는 Svelte

 

Virtual DOM이란, 브라우저에서 웹 페이지를 출력할 때 많은 비용이 소모되는 DOM 조작을 속도가 빠른 메모리 안에서 미리 구현한 후 실제 페이지에 적용하기 위해 도입된 방식으로 앞서 언급한 3 대장 프레임워크 모두가 성능 향상을 위해 사용하는 개념이다.

 

브라우저는 웹 페이지를 출력할 때 아래와 같이 복잡한 과정을 거치는데, 간단히 설명하면 HTML 문서로 DOM Tree를 생성하고, CSS로 Style 규칙을 정의한 후 이 두 개를 합쳐 Render Tree를 생성한다. (이 과정을 Attachment라고 한다.)

 

 

브라우저는 생성된 Render Tree를 기반으로 Layout (또는 Reflow) 과정을 거치는데, 이 단계가 바로 브라우저에서 가장 많은 시간과 자원을 사용하는 단계이다. 따라서 웹 페이지의 반응성 및 성능을 향상하기 위해서는 Layout 과정을 최소화하는 것이 좋다. 문제는 DOM을 조금만이라도 조작하더라도 위의 과정을 끊임없이 반복한다는 것이다. 10번의 DOM 조작이 일어난다면, 브라우저는 10번의 Layout 과정을 수행하는 것이다.

 

따라서 성능 향상을 위해서는 Layout 과정을 최소화하는 것이 필수이며, 이 과정에서 Virtual DOM이 사용된다. DOM이 변경되면 바로 브라우저에 반영하는 것이 아니라 메모리 상에 있는 Virtual DOM에서 여러 번의 DOM 수정을 거친 뒤 최종으로 완성된 DOM을 브라우저에 반영하는 것이다. 따라서, 브라우저는 단 한 번의 Layout만으로 최종 결과물을 출력할 수 있다.

 

하지만 Svelte는 Virtual DOM을 사용하지 않는다. Svelte는 Virtual DOM이 실제 DOM보다 대부분은 빠르지만, 100% 빠르다고 확신할 수 없다고 주장한다. Virtual DOM이 실제 DOM에 적용되는 과정을 살펴보면, 변경되기 전 Virtual DOM과 변경된 Virtual DOM을 서로 비교하여 변경된 부분만 실제 DOM에 적용하는 방식으로 이루어진다.

 

 

문제는 Virtual DOM끼리 비교하는 과정에서 오버 헤드가 발생한다는 것이다. 실제로 ReactJS의 컴포넌트에는 오버 헤드를 줄이기 위해 "shouldComponentUpdate"라는 메서드를 제공하고 있다. 이 메서드는 전달받은 state 또는 props 값에 따라 Re-render를 진행할지에 대한 여부를 알려주는 메서드이며, 상황에 따라 비교 과정을 줄여 오버 헤드를 줄이는 것이다. 즉, ReactJS는 Virtual DOM의 비교 과정에 대한 오버 헤드를 이미 신경 쓰고 있다는 것이다.

 

Virtual DOM을 사용하면 위와 같이 필연적으로 오버 헤드가 발생하기 때문에 Svelte에서는 Virtual DOM을 사용하지 않는다. Svelte는 인터프리터와 같이 런타임에서 변경된 요소를 찾느라 시간을 허비하지 않고, 컴파일러와 같이 빌드 시 실제 변경된 요소가 어디에 어떻게 변경됐는지 정확하게 찾아내는 최적화된 작업을 수행한다. (그렇다고 한다. 내부 구조는 따로 설명이 안되어있다. 영업 비밀?)

 

Svelte가 3대 프레임워크를 성능으로 이기는 것을 볼 수 있다.

 

따라서, 3 대장 프레임워크들과 달리 DOM 변경에 사용되는 오버 헤드가 없고, 런타임을 포함하지 않기 때문에 DOM 변경에 관련된 작업 (Diff 등...) 또한 필요가 없어 번들 크기가 매우 작아지는 장점이 있다.

 

실제로, 번들링의 경우 눈에 띄게 크기가 작은 것은 장점이라 할 수 있겠다.

 

진정한 반응성

 

Svelte에서 주장하는 반응성이란 Virtual DOM을 사용하여 변경된 요소를 하나하나 비교하고 찾아내어 반영하는 것이 아닌, 빌드 시간에 정확하게 어디가 어떻게 변경될지 알고 반영하는 것이라고 말한다. 빌드 타임에 이러한 작업을 수행하기 때문에 Svelte는 자신이 컴파일러라고 주장한다.

 

 

또한 Svelte는 내부적으로 Store를 기본으로 제공함으로써, 변경된 상태 값을 DOM에 빠르게 반영할 수 있도록 기능을 제공한다. (VueJS와 매우 비슷하다.)

 

 

// store.js

// 쓰기가 가능한 스토어를 생성하기 위한 Import
import { writable } from 'svelte/store';

// 쓰기가 가능한 "count" store를 외부로 Export
export const count = writable(0);
// Sample.svelte

<script>
  import { count } from './store.js';
</script>

// 쓰기 스토어 "count" 사용. 스토어 앞에 $가 있으면, 구독 / 구독 해제가 자동으로 이루어진다.
<button on:click={() => $count += 1}>
  {$count}
</button>

 

Svelte 사용 시 주의사항

 

Svelte를 사용해보니 몇 가지 불편한 점들이 느껴졌다. 실제 제품에 Svelte를 적용한다면 어떤 것들이 장애물이 될지 간단히 알아보자.

 

1) 너무 많은 것을 허용하는 코드 스타일

 

현재 회사에서 사용 중인 VueJS는 싱글 파일 컴포넌트를 사용하여 Template, Script, Style 영역으로 나눠 모듈의 구현이 길더라도 어느 정도는 가독성이 확보되는 편이다.

 

하지만 Svelte는 하나의 모듈에 여러 가지 Root Template이 올 수도 있고 영역에 대한 순서나 위치에 대한 제약이 없기 때문에 아무런 규칙 없이 작성했다가는 유지보수 때 피를 볼 수 있을 것 같다. 프로젝트 시 반드시 팀 내에서 코드 작성 규칙을 결정하고 작업을 진행해야 될 것 같다.

 

2) IE11 이하는 어떡하지?

 

사실 이거는 이야기하기 애매한 게, Svelte가 아니더라도 다른 프레임워크도 IE 호환성에 대해 매우 많은 고민을 해야 할 것이다. 문제는 Svelte로 IE 호환성을 잡기 위해서는 다른 프레임워크 대비 몇 배의 노력과 삽질이 필요하다는 것이다. 그만큼 정보가 많지 않다.

 

3) 정보가 많이 없다

 

Svelte에 관련된 정보는 구글에서 찾아보면 많이 나오긴 하지만 ReactJS나 VueJS, Angular 대비 매우 적은 수준이다. 아무래도 알려진 게 얼마 전이다 보니 커뮤니티 자체가 많이 작다. 그나마 요즘 심심치 않게 올라오는 것 같다.


이것으로 Svelte가 무엇인지, Svelte가 주장하는 장점이 무엇인지 또 사용 시 주의사항에 대해 알아보았다. 다음 글에서는 Svelte로 개발하기 위한 환경 구성 방법에 대해 알아보도록 하겠다.

 

참고 링크

https://svelte.dev/
https://daveceddia.com/svelte-intro/
https://beomy.github.io/tech/svelte/introduction-svelte/
반응형

'재주껏 하는 Front-End > Svelte (준비중)' 카테고리의 다른 글

6. 이벤트 처리  (0) 2020.09.08
5. 논리 문법 / Props  (0) 2020.09.04
4. 반응형 문법  (0) 2020.09.02
3. 기본 문법  (0) 2020.09.01
2. Quick Start Guide + VS Code 개발 환경 구성  (0) 2020.08.27