DOM 템플릿 API를 도입할 적기임
(justinfagnani.com)- 웹 플랫폼은 동적 애플리케이션 런타임으로 자리 잡았지만, 표준 DOM에는 데이터·이벤트·프로퍼티·XSS 방어·효율적 갱신을 함께 다루는 선언적 템플릿 API가 없음
- React, Vue, Angular, Lit, Svelte, SolidJS 같은 현대 프레임워크는 마크업과 데이터를 결합하는 템플릿 시스템을 핵심으로 삼고, 이는 가독성·보안·성능·정적 분석·서버 사이드 렌더링에 영향을 줌
- 과거 E4X, E4H, 내장
html템플릿 리터럴 태그는 DOM 생성에는 도움이 됐지만 DOM 갱신을 해결하지 못했고, 이제는 tagged template literals와 프레임워크 경험이 표준화 기반을 제공함 - JavaScript 기반 API는 JSX 표준화나 HTML 기반 템플릿보다 범위가 작고, JSX 변환의 컴파일 타깃이 되면서 이후 HTML 템플릿과 선언적 커스텀 엘리먼트로 이어질 수 있음
- 제안 경로는 DOM Parts, template identity, Signals, DOM 스케줄러 같은 하위 메커니즘과 맞물리며, vanilla 개발자·웹 컴포넌트 사용자·프레임워크 구현자에게 공통 기반을 제공할 수 있음
표준 DOM에 없는 선언적 템플릿 계층
- 웹 플랫폼은 역사상 가장 성공적인 애플리케이션 런타임이며, DOM API는 정적인 문서 뷰어를 동적이고 표현력 있는 런타임으로 바꾸는 기반임
- Photoshop 같은 복잡한 앱도 웹 앱으로 제공되고, 전체 UI가 Web Components로 만들어질 만큼 DOM은 강력한 API임
- 다만 현재 표준 DOM API에는 다음 작업을 한 번에 다루는 편한 방식이 없음
- 데이터에서 DOM 노드 조각 생성
- 이벤트 리스너 추가
- 엘리먼트 프로퍼티 설정
- XSS 공격에 대한 안전성 확보
- 새 데이터로 해당 DOM 조각을 효율적으로 갱신
프레임워크가 이미 증명한 템플릿의 가치
- 현대 웹 프레임워크와 렌더링 라이브러리는 마크업과 데이터를 선언적으로 결합하는 템플릿을 핵심 기능으로 사용함
- React, Vue, Angular, Preact, Lit, Svelte, SolidJS, Stencil, Quik, Ember, FAST, Polymer, Marko 등이 포함됨
- 선언적 템플릿은 명령형 DOM API보다 작성성과 읽기성이 좋음
- 보간, 이벤트 리스너, 프로퍼티 설정이 템플릿 가까이에 있어 동작의 지역성을 유지하기 쉬움
- 템플릿 시스템은 보간 값을 자동 이스케이프할 수 있어 XSS 방어에 유리함
- 좋은 템플릿 시스템은 변경이 필요한 DOM만 갱신해 대부분의 손작성 코드보다 빠를 수 있음
- 많은 템플릿 시스템은 타입 검사와 자동완성 같은 정적 분석을 지원함
- 선언적 템플릿 정의를 전체 브라우저 환경 밖에서도 해석할 수 있어 효율적인 서버 사이드 렌더링이 가능함
템플릿 부재가 만드는 비용
- 플랫폼은 거의 모든 웹 애플리케이션의 핵심 요구를 아직 직접 충족하지 못함
- 국제화 API, Temporal, Scheduler, Sanitizer처럼 템플릿도 표준 플랫폼 기능으로 다룰 만함
- 사용자는 앱 다운로드 시간, 렌더링 오버헤드, 보안이 약한 앱의 영향을 받음
- 템플릿 라이브러리 코드는 최선의 경우 몇 kB, 최악의 경우 100kB 이상일 수 있음
- 몇 kB도 초기 인터랙티브 렌더링 예산에서는 큰 비중이 될 수 있음
- 개발자는 기본적인 작업에도 라이브러리, npm, CDN에 의존해야 함
- 단순 정적 파일과 DevTools의 유용성이 줄어듦
- 스택 간에 이식 가능한 기본 템플릿 지식이 없음
innerHTML같은 네이티브 DOM 생성 API는 기본적으로 안전하지 않음
- 프레임워크와 템플릿 라이브러리는 작성성, 렌더링 속도, 갱신 속도, 보안, 코드 크기 사이에서 어려운 절충을 해야 함
- 웹 플랫폼은 Flutter, SwiftUI, Jetpack Compose 같은 네이티브 플랫폼과 경쟁함
- 이들 플랫폼은 템플릿 유사 시스템을 내장하고, 앱 설치와 컴파일 언어를 사용하며, 몇 kB 번들 크기에 덜 민감함
지금 다시 시도할 수 있는 이유
- 과거에도 템플릿에 가까운 플랫폼 제안이 있었음
- E4X는 Firefox와 Flash에 실제로 포함됐음
- E4H는 Ian Hixie가 단순화한 아이디어였음
- 2012년 무렵 내장
html템플릿 리터럴 태그 프로토타입도 있었음
- 과거 시도는 DOM 생성에는 도움이 됐지만, 갱신을 해결하지 못했기 때문에 충분한 해법이 되기 어려웠음
- 현재는 프레임워크들이 충분한 사용 사례를 만들었고, 사용자 영역 템플릿 해법도 시간이 갈수록 더 비슷해지고 있음
- 프레임워크를 쓰지 않는 개발자와 웹 컴포넌트 커뮤니티에서도 편한 DOM 조작과 반응성 API 수요가 있음
- DOM Parts 같은 저수준 DOM 갱신 프리미티브 제안이 진행 중임
- 더 높은 수준의 선언적 템플릿 API는 프레임워크 구현 부담을 줄이고, 저수준 API 제안을 검증·보완할 수 있음
문법과 의미론의 공통분모
- 인기 있는 클라이언트 사이드 템플릿 시스템은 대부분 마크업과 바인딩을 결합하는 구조를 공유함
- 표현식 구분자, 제어 흐름, 바인딩 타입 표시자는 조금씩 다르지만 공통점이 더 큼
- HTML 기반 Vue, Angular, Svelte와 JavaScript 기반 React, Lit, Solid 사이에도 유사성이 있음
- JavaScript 기반 API에서는 템플릿이 보통 표현식이고, 합성은 템플릿 표현식 중첩이나 참조로 이뤄지며, 제어 흐름은 JavaScript가 담당함
- 많은 JavaScript API 기반 시스템은 템플릿 표현식에서 DOM 설명을 반환한 뒤, 별도
render함수 호출로 적용함- 대다수는 같은
render호출로 DOM을 갱신함 - 일부는 세밀한 반응성으로 이 방식을 피함
- 대다수는 같은
- E4X와 E4H는 JSX처럼 JavaScript에 마크업을 넣는 새 문법을 추가했지만, DOM 설명이 아니라 DOM 조각 자체를 반환함
- 초기 DOM 생성에는 좋았지만 갱신은 여전히 명령형으로 남았음
오늘의 JavaScript로 표현 가능한 API
- JavaScript에는 HTML 같은 임베디드 DSL을 위한 tagged template literals가 이미 있음
- 새 JavaScript 문법을 추가하지 않고도 DOM API에서 템플릿을 표현할 수 있음
- 인기 라이브러리들이 이 접근이 잘 작동한다는 점을 보여줌
- 새 문법 없이 제안을 진행할 수 있다는 점은 표준화 현실성에 중요함
JSX와 네이티브 템플릿 API의 관계
- tagged template literals는 ES2015의 강력한 기능이지만, 사용자 영역 컴포넌트 시스템에서는 JSX보다 문법 오버헤드가 큼
- JSX는 인기가 높지만, 문법만 있고 런타임 의미론이 없음
- 표준화하려면 단순히 새 문법을 추가하는 것을 넘어 의미론을 정의해야 함
- 주변에 정의된
createElement()호출로 취급하는 방식은 배제됨 - 객체 트리를 만드는 방식은 정적 부분과 동적 부분을 섞어 더 효율적인 갱신 패턴을 막을 수 있음
- Records and Tuples 제안이 진행 중이었다면 JSX가 박스가 있는 Records를 만들 가능성이 있었지만, 해당 제안은 특히 record identity와 box 부분에서 정체돼 있음
- JSX 같은 문법과 의미론이 완전한 DOM 템플릿에 적합한지 검증하려면 대상 템플릿 시스템이 필요함
- React의 템플릿은 DOM 엘리먼트의 프로퍼티와 이벤트에 명시적으로 바인딩하거나 엘리먼트에 지시자를 적용하는 방식이 없음
- 현재의 비표준 JSX는 런타임 의미론이 없는 순수 문법이므로, JSX를 tagged template literal로 변환하는 컴파일러를 만들 수 있음
- JSX-to-Lit 같은 사례가 이미 있음
- 네이티브 템플릿 API는 개발자가 원하는 문법을 선택할 수 있는 컴파일 타깃이 될 수 있음
HTML 기반 템플릿보다 JavaScript API를 먼저 보는 이유
- 많은 웹 개발자는 완전한 기능의 HTML 기반 템플릿 시스템을 원함
- 웹 컴포넌트 사용자, 프레임워크 사용자, vanilla 개발자 커뮤니티에 수요가 있음
<template>엘리먼트, declarative shadow DOM, Web Components가 이런 기능을 제공할 것으로 기대했던 개발자도 있음
- HTML 기반 템플릿은 JavaScript 기반 API보다 훨씬 큰 작업임
- 바인딩 문법
- 표현식 언어
- 제어 흐름 구문
- 템플릿 갱신 메커니즘
- 네이티브로 HTML 기반 템플릿 정의를 로드하는 방식도 없음
- Web Components v0의 HTML Imports는 사라졌고, HTML Modules는 아직 없음
- HTML 템플릿을 JavaScript 모듈 안에 넣어야 한다면, 데이터와 같은 렉시컬 스코프에서 JavaScript 표현식을 쓰는 편이 더 낫다는 판단임
- Polymer 3는 Polymer 2의 HTML 템플릿을 JavaScript로 옮겼고, 이는 Lit으로 직접 이어짐
- JavaScript가 스크립트 같은 일을 맡게 하는 편이 코드가 적고 경험이 더 좋았음
- JavaScript API는 HTML 기반 API의 부분집합이자 발판이 될 수 있음
- JavaScript API가 들어가 검증되면 HTML API는 바인딩, 표현식, 제어 흐름, 모듈 시스템을 정의하는 과제로 남음
반응성 모델의 선택지
- 초기 DOM 템플릿 제안은 갱신을 포함하지 않았지만, 사용자 영역 시스템은 반응성 모델과 구현 접근을 충분히 탐색해 왔음
- 대표적인 반응성 접근은 세 가지로 묶을 수 있음
- React의 VDOM과 diffing
- Lit의 template identity
- Solid와 Svelte, Vue, Angular 등에서 쓰이는 Signals와 세밀한 반응성
- diffing은 이해하기 쉽고 어떤 데이터에도 작동하지만, 다른 접근보다 느림
- diffing 알고리듬 차이가 관찰 가능할 수 있음
- 하나의 diffing 알고리듬을 표준화하고 플랫폼 엔지니어에게 오버헤드를 받아들이게 하기는 어려움
- template identity는 현재 템플릿으로 렌더링된 DOM이면 갱신하고, 아니면 교체하는 방식임
- 빠르고, 다수 사용 사례에서 diffing과 매우 비슷한 결과를 냄
- tagged template literals, JSX 변환, HTML 기반 템플릿과 잘 맞음
- 의미론이 단순해 명세화하기 쉬움
- Signals는 새 반응형 DOM API와 템플릿 API에 포함될 만한 모델임
- JavaScript Signals 제안이 있지만 아직 플랫폼의 네이티브 기능은 아니며 채택이 보장되지 않음
- Signals 기반 시스템은 모든 데이터를 signal로 감쌀 때 가장 잘 작동함
- signal이 아닌 데이터와 signal을 만들지 않는 플랫폼 API도 많기 때문에, 재렌더링은 그런 변경을 반영하는 쉬운 방법임
- template identity와 Signals는 공존할 수 있음
- 바인딩에 signal만 전달하는 템플릿은 재렌더링 없이 signal로만 갱신될 수 있음
- signal이 아닌 데이터를 참조할 수 있는 템플릿은 재렌더링이 필요함
- 보통 재렌더링은 반응형 컴포넌트 프로퍼티 같은 컴포넌트나 프레임워크 계층이 자동으로 수행함
표준화 논의와 남은 과제
- 네이티브 선언적 JavaScript 템플릿 API 논의는 WICG webcomponents#1069에서 시작됨
- 이 API는 DOM 생성 API의 논리적인 다음 단계가 될 수 있음
- vanilla 웹 개발자에게 작성성 좋고 안전한 DOM 생성 프리미티브가 됨
- Lit, FAST, HyperElement 같은 기존 웹 컴포넌트 라이브러리에 바로 유용함
- 원시 Web Components API 사용자에게 유용하고, 더 완전한 반응형 컴포넌트 정의 API로 가는 발판이 됨
- 새 프레임워크가 이 API를 기반으로 만들어질 수 있음
- 기존 프레임워크는 컴파일 타깃, 런타임 백엔드, 직접 지원 대상으로 사용할 수 있음
- 재렌더링 기법과 Signals 모두에 유용함
- 선언적 HTML 템플릿과 선언적 커스텀 엘리먼트로 가는 발판이 됨
- 합의하고 명세화할 API 표면이 상대적으로 작음
- 템플릿 의미론을 정의하는 데 도움을 줌
- 이 작업은 DOM Parts 제안의 완성과 맞물림
- DOM Parts를 정의하고 유용성을 입증하는 데도 기여함
- 표면 API와 문법은 크지 않지만, 동작 공간과 하위 DOM Parts API는 큼
- 세밀한 반응성에는 어떤 형태의 DOM 스케줄러도 필요함
- 정해야 할 항목, 합의할 항목, 명세화할 항목, 테스트할 항목이 많아 협업이 필요함
- 관심 있는 개발자는 webcomponents#1069에 댓글을 남기거나 Bluesky로 연락할 수 있음
댓글과 토론
Hacker News 의견들
-
“템플릿에 좋은 문법이 어떤 건지 안다”는 말은 웃음이 나올 정도임. 아직 전혀 모른다고 봄. 좋은 템플릿은 기호적 문법이라기보다 거의 확실히 시각적인 도구에 가까워서, 예전 Dreamweaver 같은 도구가 성공했고 디자이너들이 Photoshop 같은 도구로 배우는 이유도 거기에 있음
또한 XSLT를 다시 만들려는 시도처럼 보여서 아쉽다. 누군가는 결국 well-formed가 아닌 조각들을 템플릿화하고, 합치면 well-formed가 되는 무언가를 만들고 싶어 할 수밖에 없음. 페이지 안에서 서로 연결돼 있지만 같은 트리에 있지 않은 엔티티도 마찬가지임. 평범한 마크업의label과for가 쉬운 예임
가능하다면 마크업의 표준 문서 레이아웃이라는 루브 골드버그 장치에 모든 템플릿을 억지로 맞추려는 시도가 줄었으면 함. 절대 위치 지정을 신중하게 쓰면 꽤 잘 되는 일을 재현하려고 사람들이 말도 안 되게 복잡한 길을 감. 맞추려면 계산이 필요할 수는 있지만, 왜 같은 데이터에 대해 기계가 그 계산을 계속 반복하도록 강제해야 하는지 모르겠음- XML을 좋아한 적은 없지만, XSLT는 그 생태계를 구원할 만한 킬러 기능이었고 지금도 그렇다고 봄. 아직 브라우저에서도 널리 지원됨
XML이 설정, 프로세스 간 통신 같은 부적절한 곳에서는 유행했지만, XSLT라는 훌륭한 변환 능력을 가진 마크업 언어로서 빛날 수 있는 곳에서는 시들해진 게 아쉬움
XSLT가 무너진 지점은 진짜 DSL이라는 점, 그것도 선언적·순수·함수형 DSL이라는 점이었다고 봄. 사람들은 DSL을 말로는 크게 띄우지만, 실제로는 인기 있는 호스트 언어의 절차적 의미론을 추상화하지 못하는 단순한 문법 놀이에 그치는 경우가 많음. 어려운 일을 사소하게 만들어 주는 잘 설계된 DSL을 만나면, 사람들은 배우려 하지 않음 - 그 결론에 어떻게 도달했는지 모르겠음. 말하는 건 템플릿 생성 방식이 아니라 HTML+CSS 전반에 대한 불만처럼 보임
그리고 왜 절대 위치 지정이 나오는지도 의문임. HN에서 이런 얘기를 반복해서 보는데, 물론 절대 위치 지정은 쓸 곳이 있고 많은 경우 필요함
하지만 페이지나 앱 레이아웃에 쓰면, 경험상 대부분은 콘텐츠나 화면 크기가 조금만 바뀌어도 무너지는 악몽이었음. 인쇄 신문 레이아웃조차 타이포그래피가 얽혀 있어서 그렇게는 못 함
CSS를 많이 다루던 때, 누군가 절대 위치 지정으로 “거의 다 된” 레이아웃을 만들어 둔 상태에서 작업을 이어받으면 고치는 데 시간이 엄청 들었고, flex나 일반 흐름 같은 방식으로 다시 만드는 편이 항상 빨랐음. 절대 위치 지정을 주 레이아웃 도구로 쓰면 문제가 사실상 고칠 수 없는 수준이었기 때문임
calc()와 뷰포트 단위를 써서 말이 되는 기법이 있을 수는 있겠지만, 경험상 완전히 정적인 콘텐츠와 뷰포트 크기가 아니라면 절대 위치 지정은 레이아웃에 적합하지 않음 - 웹에는 문서가 어떤 기기 크기, 비율, 방향, 기능에서도 좋아 보여야 한다는 요구가 있음. 일반 앱, 예를 들면 Windows 앱에는 이런 요구가 없고, 모바일 앱에는 표준화된 몇 가지 크기가 있음. 웹만 둘 다 갖고 있음
- React와 Svelte 사이에는 표면적인 유사성만 있다고 봄. 둘 다 HTML에 크게 기반한 문법을 쓰지만 작동 방식은 매우 다름
React는 대체로 일반 JavaScript 함수가 JSX 형태의 마크업 지연 표현을 반환하는 방식으로 동작하는 유일한 주요 프레임워크임. React에는 템플릿 수준의 반복이나 조건부 렌더링 개념이 없고, 그건 일반 JavaScript로 처리함 - 웹 플랫폼의 진전을 주장하는 사람 앞에서 비웃는 건 그리 좋은 태도가 아님. 그 진전은 모두에게 이익이 됨
그리고 이제는 좋은 템플릿 문법이 뭔지 안다고 봄. 기본적으로 JSX임. React를 별로 좋아하지 않는 입장에서도 그렇게 말할 수 있음. JSX는 웹 전체를 휩쓸었고 여러 프레임워크에 맞게 변형됐으며, JavaScript 템플릿 시스템들이 템플릿을 표현식으로 다루고, 중첩으로 합성하며, 특정 템플릿 문법 대신 JavaScript 자체로 제어 흐름을 처리하는 공통 속성으로 수렴했다는 건 부정하기 어려움
- XML을 좋아한 적은 없지만, XSLT는 그 생태계를 구원할 만한 킬러 기능이었고 지금도 그렇다고 봄. 아직 브라우저에서도 널리 지원됨
-
반복해서 배운 기본 교훈은 API/ABI는 최종 상태가 아니다라는 것임. 애플리케이션의 요구는 안정된 API 하나로 영구히 충족되지 않고, 미래의 모든 문제를 앱 레벨 문제로 돌릴 수도 없음
이 제안은 플랫폼의 공통 문제가 React 같은 상위 계층에서 해결되다가, 결국 문제로 인정되면 아래로 내려가는 과정을 잘 보여줌. 폴리필도 같은 예임
이런 제안이 성공하면 잠시 주목받지만, 유용한 수명의 대부분은 사람들이 우회하려 드는 낡은 것이 되어 버림. DOM API, ECMA 버전, 오래된 브라우저, 시스템의 일부라서 건드릴 수 없는 모든 유용한 기술이 그랬음
엔트로피, 확장, 하위 호환성을 주요 사용 사례로 놓고 생각할 수는 없을까- 웹 표준의 모든 기능은 세심하게 유지보수해야 할 추가 코드이고, 표준 준수 브라우저를 만들려는 누구나 구현해야 하는 추가 코드이기도 함. https://servo.org/ 같은 프로젝트가 시간이 지나며 따라잡을 기회를 얻었으면 하지, 계속 늘어나는 범위를 쫓기만 하길 바라지는 않음
웹 플랫폼이 네이티브 플랫폼의 모든 가능한 능력을 갖추길 원함. 물론 개인정보 보호와 샌드박싱 제약은 지켜야 함. 그리고 웹 개발자의 개발 경험도 훌륭해지길 원함
하지만 이는 복잡성 증가의 결과와 균형을 이뤄야 함. 이 경우 네이티브 템플릿이 정말 개발 경험을 개선하는지 확신이 안 듦. 이득이 비용을 넘는다고 보이지 않음 getElementById는 25년쯤 안정적이지 않았나 싶음. “안정된 API 같은 건 없다”는 말은 오래가는 인터페이스를 만들 능력이 없거나 만들 의지가 없는 사람들이 하는 말임. 우주의 법칙이 아니라 개인적 체념에 가까움. 반례는 엄청 많음
애플리케이션 요구는 다른 요구처럼 무한함. 그 요구는 작동하는 API를 깨서가 아니라 새 API를 추가해서 만족시키는 것임- 웹에서는 API/ABI가 최종 상태가 맞음. 일단 웹에 공개되면, 누군가는 그 정확한 형태에 영원히 의존하게 됨
그래서 20년 전 결정 때문에 아직도smooshgate같은 사태에 휘말리는 API가 있음: https://developer.chrome.com/blog/smooshgate - 그 과정에서 기본 기능은 또 한 단계 올라감. 사용자 영역 요구가 항상 새 빈틈, 사용 사례, 사각지대를 찾아낼 거라는 이유만으로 점진적 업데이트가 무가치해지는 건 아님
- 그래서 버전을 두고 예전 버전과의 하위 호환성을 유지하며, “오래된” 인터페이스를 바꾸지 않는 것 아닌가
- 웹 표준의 모든 기능은 세심하게 유지보수해야 할 추가 코드이고, 표준 준수 브라우저를 만들려는 누구나 구현해야 하는 추가 코드이기도 함. https://servo.org/ 같은 프로젝트가 시간이 지나며 따라잡을 기회를 얻었으면 하지, 계속 늘어나는 범위를 쫓기만 하길 바라지는 않음
-
웹에는 정말 네이티브 템플릿, 반응성, 데이터 바인딩이 필요함. 수십억 사용자가 React 같은 걸 내려받고 파싱하고 실행하느라 얼마나 많은 CPU와 대역폭이 낭비되는지 상상도 안 됨
- 이제 LLM과 암호화폐가 있어서 그런 낭비는 아주 작아 보임
- TC39 Signals 제안으로 그 일부는 진전되고 있음
- 양방향 데이터 바인딩과 JSX 복제본 정도면 사실 대부분에게 충분함
- React는 템플릿이라고 보기 어렵지 않나
-
Signals 부분이 많은 걸 말해 주고, 아이디어는 훌륭하지만 실질적으로는 어렵다는 점을 잘 보여줌
글쓴이가 왜 Signals를 좋아하는지는 이해됨. 충분히 큰 프로젝트마다 반쯤 만든 DAG 계산 트리가 있고, 언어가 하나를 표준화하는 건 말이 됨
하지만 이런 추상화는 인지 비용과 구현 비용이 큼
대부분의 엔지니어링이 그렇듯 문제는 절충임. React 모델은 전역 상태를 갱신하고 전부 다시 렌더링하므로 느리지만 머리에는 쉬움. Signals 모델은 빠르지만 너무 많은 노력이 듦
대부분의 앱은 미친 듯이 빠를 필요가 없고, 사람들은 더 단순한 React를 선택할 것임
그런데 Signals는 템플릿과 별 관련이 없지 않나. 그렇다면 왜 선택해야 하는가. 템플릿과 Signals를 별개로 가질 수 있지 않나
템플릿을 생각하다 보면 DOM에 템플릿 노드를 어디에 끼워 넣고, 변경될 때 어떻게 갱신할지 알려주는 방법이 필요해짐. 바로 이 지점에서 이런 제안들이 실패함
API는 여기서 한쪽을 골라야 함. 기술적으로 둘 다 허용할 수도 있겠지만 끔찍함. 개발자들은 어느 쪽이어야 하는지 절대 합의하지 못할 것임
UI의 큰 문제는 늘 어떻게 정의하느냐가 아니라 어떻게 갱신하느냐였음. Microsoft는 MVC, MVP, MVVM 등 많은 모델을 정의하려 했고 실패했으며, 모두 고통스러웠음. 그러다 imgui가 “UI에 상태가 아예 없다면?”이라고 말했고, 그건 꽤 좋지만 CPU에는 부담이 큼
어쩌면 웹 앱 성공의 가장 큰 이유 중 하나는 DOM이 데이터를 뷰에 묶는 방식을 강제하지 않았기 때문일 수 있음. 그래서 우리는 프레임워크 지옥에서 벗어나기 어려울지도 모름- 이제 Signals나 프록시, 다른 반응형 원시 요소에 의존하지 않고도 세밀한 차이 계산을 잘하는 프레임워크가 여럿 있음. 기본적으로 위에서 아래로 내려가는 React 모델이지만 훨씬 빠르고, hooks나 수동·낭비적인 의존성 배열 같은 이상한 개념도 없음
개인적으로 좋아하는 건 ivi-js임: https://github.com/localvoid/ivi
벤치마크만 이기겠다는 생각으로 결국 도달할 수 있는 가장 빠르고, 가장 못생기고, 명령형이며, 유지보수 불가능한 바닐라 JavaScript보다 겨우 8% 느릴 뿐임
https://krausest.github.io/js-framework-benchmark/2025/table... - Microsoft가 여러 시기에 그 모델들을 사용하긴 했지만, 직접 정의한 건 MVVM뿐임. MVC는 Xerox PARC, MVP는 Taligent에서 나왔음
- 개발자 입장에서도 개발자의 머리가 조금 더 힘들더라도 하드웨어, 대역폭, 지구에 더 쉬운 쪽을 기꺼이 택하겠음
대부분의 앱이 미친 듯이 빠를 필요는 없다는 말보다, 앱이 가벼워야 한다는 점을 더 인정했으면 함
사람들이 React를 더 단순해서 고른다는 말에는 동의하지만, 바로 그 이유로 React가 마음에 들지 않음
- 이제 Signals나 프록시, 다른 반응형 원시 요소에 의존하지 않고도 세밀한 차이 계산을 잘하는 프레임워크가 여럿 있음. 기본적으로 위에서 아래로 내려가는 React 모델이지만 훨씬 빠르고, hooks나 수동·낭비적인 의존성 배열 같은 이상한 개념도 없음
-
JSX를 채택하기보다, Kotlin이 리시버와 빌더로 DSL에 일반화된 문법을 제공하고 그 문법이 컴포넌트 계층 표현에도 잘 맞는 방식에 더 가까웠으면 함
HTML 템플릿뿐 아니라 설정과 여러 종류의 구조를 표현하는 데도 널리 유용할 것임
템플릿과 데이터 바인딩의 실제 의미론은 Jetpack Compose에서 보듯 그런 문법 기능을 쓰는 표준 함수 집합으로 두면 됨- 많이 필요하지도 않음. 반복, 속성에 대한 조건문, 노드에 대한 조건문이면 됨. 사실 그 정도는 언어 간 공통 기능으로도 가능함
-
이 글은 이 분야에서 가장 경험이 많은 사람 중 하나가 쓴 것이라는 점도 중요함. Lit / Polymer의 주요 작성자이고, Google에서 Web Components 작업을 하며 웹 플랫폼 일부가 된 핵심 DOM 사양들에 기여한 사람임
- 오히려 반쯤 익은 사양으로 무모하게 밀고 나가 해결한 것보다 훨씬 많은 문제를 만든 사람 중 하나라고 봄. 사용자 영역이 이미 하고 있는 일들을 겨우 따라 하려고 20개가 넘는 새 웹 사양을 요구하는 “해결책”을 밀어붙였고, 100% 동의하지 않는 사람들은 무시하거나 가스라이팅했음
Safari는 15년 전부터 여기에 선언적 방식이 있어야 한다고 주장했음
- 오히려 반쯤 익은 사양으로 무모하게 밀고 나가 해결한 것보다 훨씬 많은 문제를 만든 사람 중 하나라고 봄. 사용자 영역이 이미 하고 있는 일들을 겨우 따라 하려고 20개가 넘는 새 웹 사양을 요구하는 “해결책”을 밀어붙였고, 100% 동의하지 않는 사람들은 무시하거나 가스라이팅했음
-
선언적 템플릿이 사실 jQuery보다 더 나쁘다고 느끼는 사람이 또 있는지 궁금함. React를 거의 10년 써 왔지만, SPA가 복잡해질수록 DOM을 명령형으로 직접 제어하고 싶어짐
이유는 DOM이 새는 추상화이고, 어느 수준에서는 마지막 쓰기가 이기는 방식이 더 낫다고 느끼기 때문임
선언적 템플릿이 그걸 처리하려는 건 알지만, 컴포넌트 간에 변경 가능한 상태를 공유하기 시작하면 이 방식은 아주 빨리 무너짐- React 쪽 사람들은 DOM API를 직접 호출하는 걸 큰 죄악처럼 여기는 면이 있음. 때로는
ref를 잡고, 감히 말하자면id로 컴포넌트를 찾아서 직접 처리해도 괜찮음. 실제로 “빠르고” 재렌더링이 적은 라이브러리들, 예를 들면 폼 라이브러리들이 그렇게 함 - React를 좋아하지는 않지만 이 감각에는 동의하지 않음. 우선 이미 선언적 DOM에서 벗어나
innerHTML과ref로 마음껏 할 수 있음
둘째, DOM을 명령형으로 제어하면 선언형보다 덜 번거롭게 할 수 있는 일이 뭔지 모르겠음.attachShadow(),showModal()같은 특정 메서드 정도만 떠오르는데, 그것도 10줄짜리 컴포넌트로 감싸면 선언적으로 만들 수 있음 - 완전히 동의함. React 같은 것이 별도의 HTML과 jQuery를 쓰는 것보다 조금이라도 낫다고 납득시킨 예를 아직 하나도 못 봤음
- React 쪽 사람들은 DOM API를 직접 호출하는 걸 큰 죄악처럼 여기는 면이 있음. 때로는
-
Ryan Carniato와 Solid JS는 아직 Signals로 가능한 일을 탐색 중인 것으로 알고 있음. 이 영역의 사용자 영역 탐색이 완전히 끝났다고 보지 않고, 추가 혁신이 가능할 수 있음
- 웹 개발 거품 밖에도 증분 계산 문제 영역에 흥미로운 연구가 많고, 자기 조정 계산, 즉 Signals조차 그다지 흥미로운 축은 아님
-
방향성은 마음에 들지만, 그 전에 브라우저에 더 낮은 수준의 API 몇 가지가 먼저 들어가야 한다고 봄
모두가 표준 템플릿 시스템에 합의하기는 거의 불가능할 것임. 대신 브라우저가 할 수 있는 일은 DOM에 차이를 성능 좋게 네이티브 방식으로 적용하는 낮은 수준의 API를 제공하는 것임
브라우저에 이런 게 네이티브로 있으면 정말 좋겠음
element.applyDiff(DocumentFragment | string, { method: 'innerHTML' | 'outerHTML' })
이 방식은 요소 포커스, 입력값, 오디오·비디오 플레이어 상태를 유지하고 속성을 변경하는 등 방해가 적은 방식으로 차이를 적용할 수 있음. Idiomorph 같은 JavaScript 라이브러리가 이런 일을 하지만, 네이티브 해법은 훨씬 더 빠를 가능성이 있음- 글에는 유용한 낮은 수준 API가 될 수 있는 DOM part 제안 링크가 있음. VDOM 기반 프레임워크에는 잘 맞지 않겠지만, 다른 프레임워크에서는 작동 방식을 단순화하고 최적화 여지도 늘릴 수 있음
프레임워크 없는 프로젝트에도 유용할 것이고, Signals 제안까지 채택된다면 특히 더 쓸모 있을 것임
- 글에는 유용한 낮은 수준 API가 될 수 있는 DOM part 제안 링크가 있음. VDOM 기반 프레임워크에는 잘 맞지 않겠지만, 다른 프레임워크에서는 작동 방식을 단순화하고 최적화 여지도 늘릴 수 있음
-
Records and Tuples 제안은 정체된 정도가 아니라 철회됐음. https://github.com/tc39/proposal-record-tuple/issues/394
그 자리는 https://github.com/tc39/proposal-composites가 대체했음