이국범님의 프로필 사진

이국범

FE

lit-html의 diff알고리즘은 기존 가상DOM 대비 효율적이다

해커뉴스를 둘러보다가 우연히 lit 라이브러리 개발팀으로 추정되는 사람의 글을 봤다 그는 lit의 우수성에 대해 열변을 토하고 있었는데 그 중 하나가 lit의 diff 알고리즘이었다. 그것을 기존의 virtual dom과 비교해서 우월함을 입증하고 있었는데 그 내용을 적어볼까 한다 react로 대표되는 가상 dom의 diff알고리즘은 하나의 react 엘리먼트가 변경되면 그 전체 내용을 실제 dom에 전부 다시 그린다. 예를 들어 다음과 같은 리액트 엘리먼트가 있다고 가정하자 <div>{`나의 이름은 ${name}입니다`}<div> 여기서 변수 name의 값이 바뀐다면 전체 div를 다시 그리는 방식이다. 그런데 사실 이것은 비효율적이다. 바뀐 부분은 ${name}이므로 ${name}만 리페인팅 하면 된다. 그런데 말이 쉽지 그게 어떻게 되겠는가? 그렇게 마이크로 단위로 실제 DOM에게 리페인팅 명령어를 보낸다는 것은 쉽지 않다. 그런데 lit에서는 이게 된다. lit에서는 ${name}의 값만 변경되면 ${name}만 변경하라고 브라우저 DOM에게 명령어를 보낼 수 있다. 이렇게 하면 실제로 불필요한 DOM조작을 줄일 수 있고 CSSOM을 갱신하고 브라우저에 리페인팅 하는 시간을 대폭 감소할 수 있다. 이것이 가능한 이유는 두 가지가 있다 1. 웹 컴포넌트가 가상DOM이 아닌 네이티브 컴포넌트이다. 즉 문자열 그대로 DOM에 붙여넣기 할 수 있다 2. diff 알고리즘에 Tagged Template Literal을 사용한다 Tagged Template Literal은 함수 호출시 인자를 Template Literal로 표현하는 방식이다 (name) => html` <div>Hello, ${name}</div> `; 위와 같은 코드에서 html뒤에 ``로 감싸여진 부분이 Tagged Template Literal에 해당된다 위의 예제에서 Tagged Template Literal의 ${name}은 변경이 가능하지만 다른 부분은 정적 html string이므로 불변이다. 따라서 불변인 부분은 제쳐두고 변할 수 있는 값들만 별도로 모아두어 자료구조를 형성한다. 이 자료구조를 TemplateResult라고 한다. 이 자료구조는 array-like하게 되어있어서 배열을 순차적으로 순회하며 변화가 생겼는지를 체크한다 변화를 감지하면 네이티브 브라우저의 API를 호출하여 변경된 부분만 변경하라는 신호를 DOM에게 보낸다. 이 변경할 수 있는 부분은 별도의 text node로 되어있어서 Node.textContent나 Element.setAttribute 등을 호출하여 변경하면 그 외에 변경되지 않은 부분은 건드리지 않아도 된다. 이렇게 듣고 보면 꽤 간단한 방법 같지만 본인은 매우 혁신적인 방법이라고 생각한다. Tagged Template Literal을 이런 식으로 응용할 줄은 몰랐다. 이 방법을 react에도 적용해 볼 수 있을까? 글쎄.. 방법이 떠오르지 않는다. 아마도 가상DOM 기반의 프레임워크는 이렇게 마이크로 단위로 DOM을 수정하는 것이 쉽지는 않을 것이다 결론 : 나는 lit에 영업당했다

다음 내용이 궁금하다면?

또는

이미 회원이신가요?

2023년 3월 18일 오후 1:18

조회 238

댓글 0