- 웹 플랫폼은 동적 애플리케이션 런타임으로 자리 잡았지만, 표준 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로 연락할 수 있음