통칭 스벨트
스벨트가 공식 홈페이지에서 부터 대표적으로 내미는 것은 이것이다.
Write less code
코드가 길어질수록 버그가 날 확률이 높으니 아예 코드량을 줄이자!
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>
);
};
<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>
React와 svelte를 통해서 동일한 컴포넌트를 작성할떄 Svelte를 사용하는 것이 확실히 코드량을 줄여준다!
React에서는 하나의 Top Level Component를 가질 수 있다, 반면 Svelte에서는 여러 Top-level Element를 가질 수 있음!
또한 state를 가질때 React에서는 useState Hook을 사용해야하지만, Svelte에서는 assignment operator면 충분함
const [count, setCount] = useState(0);
function increment() {
setCount(count + 1);
}
let count = 0;
function increment() {
count += 1;
}
Boilerplate의 종식
reactive declaration을 통해서 React의 useMemo, useEffect, useCallback등을 대체할 수 있음
Reactive Declaration은
$: doubled = count * 2;
Svelte에서는 component의 state가 update될때 자동으로 DOM update가 되는데, 몇몇 부분은 다른 부분에 의해서 계산되어야하는 경우가 있다. 이런경우에는 $: 로 표시되는 reactive declaration을 사용할 수 있다. referenced value가 변할떄 다시 rerun하라는 뜻
변수 뿐만이 아니라, 함수, if 문등에도 사용가능함.
reactivity는 assignment에 의해서 갱신되므로 push, slice 같은 메서드들은 업데이트를 유발하지 못함.
Simple rule of thumb = 업데이트될 변수 이름은 왼쪽항에 나타나야함....
근데 이건 튜토리얼 내용이라 여기까지 하고 다음으로 넘어가면
No virtual dom
React 등의 라이브러리에서는 Virtual DOM을 사용한다. 실제 돔이 아닌 가상의 돔을 메모리에 생성하여 변경점을 가상 돔에 적용하고, 이를 한번에 실제 DOM에 적용하여 DOM 변화를 최소화하는 것이다. App이 업데이트될때마다 매번 새로운 가상 돔을 만든다.
가상 돔이 느린 것은 아니지만, 약점이 있다. 리액트의 초기 의도는 성능 변화 걱정없이 매번 single state change를 앱에 리렌더할 수 있다는 것이었다. 실제론 그렇지 않은게, 그랬다면 shouldComponentUpdate 등의 최적화는 필요 없었을 것임.
shouldComponentUpdate를 쓰더라도 앱의 가상돔 업데이트하는 건 할게 많음. 그래서 React 팀에서는 React Fiber를 통해서 작은 chunk로 나누는 방법을 고안했는데, 이는 실제 업데이트할 총량을 줄이진 못하지만, 메인 쓰레드를 오랫동안 막진 않는다는 것임.
Overhead는 어디서 오는가
diffing은 무료가 아니다. 가상돔의 이전 스냅샷과 현재 가상돔을 비교하지 않고는 real DOM 업데이트가 안됨. 이전것과 비교할떄 동일한 DOM node인지, 변한 attribute가 있는지, 요소를 내려가면서 계속 비교해야함.
현재 모던 프레임워크에서 지원하는 diffing 알고리즘은 상당히 빠르지만, overhead는 Component 그 자체에서 오는 경우가 잦다.
function MoreRealisticComponent(props) {
const [selected, setSelected] = useState(null);
return (
<div>
<p>Selected {selected ? selected.name : 'nothing'}</p>
<ul>
{props.items.map(item =>
<li>
<button onClick={() => setSelected(item)}>
{item.name}
</button>
</li>
)}
</ul>
</div>
);
}
props.items 항목의 변경 여부와 상관없이 상태 변경마다 인라인 이벤트 핸들러가 포함된 새 <li> 리스트를 만듦. 이것도 충분히 빠르지만 이러지 않으면 더 빠름!
사소한 것이라도 불필요한 일을 하는 위험성은 후에 딱히 최적화할 곳을 찾지 못하는 병목 현상을 일으킴
내일은 튜토리얼 따라해봐야지
'TIL' 카테고리의 다른 글
TIL 2022-04-20 svelte tutorial 5 (0) | 2022.04.20 |
---|---|
TIL 2022-04-19 Svelte Tutorial 1~4 (0) | 2022.04.19 |
TIL 2022-04-07 Immer (0) | 2022.04.07 |
2022-04-04 Map, WeakMap, Array.from (0) | 2022.04.04 |
TIL 2022-03-23 HTML 요소 (0) | 2022.03.23 |