Angular, AngularJS, ionic을 만든 3명이 현재 CTO & Main Contributors

Qwik은 클라이언트에서 즉시 시작되는 재개 가능한(Resumable) 애플리케이션을 구축하기 위한 프런트엔드 프레임워크입니다.
사용자 트리거 작업을 수행하는 데 꼭 필요한 코드만 다운로드하고 실행한다는 철학에 집중하여 이를 달성합니다.
Qwik은 웹 애플리케이션 구축에 대한 근본적으로 새로운 접근 방식을 나타내는 세분화된 지연 로딩 프레임워크입니다.
사이트와 앱은 애플리케이션 복잡성에 관계없이 약 1kb의 JS로 부팅할 수 있으며 규모에 따라 일관된 성능을 달성할 수 있습니다. 대부분의 JS를 다운로드하거나 실행할 필요가 없는 방식으로 설계되었기 때문에 빠릅니다. 속도는 다른 프레임워크가 수행해야 하는 작업(예: 수화(hydration))을 수행하지 않는 데서 비롯됩니다.
What is the problem?
최신 웹 사이트는 대화형이 되려면 방대한 양의 JavaScript가 필요합니다. 너무 많은 JavaScript는 두 가지 문제로 나타납니다.
- Network bandwidth — 많은 양의 코드가 클라이언트에 전달되므로 느린 네트워크에서는 시간이 오래 걸릴 수 있습니다.
- Startup time — 클라이언트에서 사이트를 대화형으로 만들기 위해 코드를 (수화(hydration)의 일부로) 실행해야 합니다.
애플리케이션이 더욱 복잡해짐에 따라 코드의 양은 멈출 기미 없이 꾸준히 증가했습니다. 복잡성이 증가하면 더 많은 코드가 필요합니다. 이 모든 코드는 사이트 시작 성능에 부정적인 영향을 미칩니다.
httparchive.org의 이 그래프에서 볼 수 있듯이 브라우저로 전송되는 JavaScript의 양이 꾸준히 증가하고 있음을 잘 알고 있습니다.


매년 CPU는 더 빨라지고 있지만 대부분의 속도 향상은 향상된 병렬 처리에서 비롯됩니다. 그리고 최근 몇 년 동안 코어당 성능 향상이 느려지고 있습니다. 따라서 오늘날 CPU 성능 향상의 주요 동인은 단일 코어의 개선이 아닌 다중 코어의 병렬 처리에서 비롯됩니다.
하지만 설상가상으로 JavaScript는 단일 스레드입니다. 따라서 복잡한 사이트에서는 최신 멀티 코어 CPU를 활용할 수 없습니다.
New goal “O(1)
우리에게 필요한 것은 새로운 패러다임입니다. 애플리케이션 복잡성에 관계없이 로드 시간이 일정한 프레임워크가 필요합니다. 브라우저에 다운로드하는 JavaScript의 양은 매년 증가하고 있습니다. 우리가 사용하는 프레임워크가 O(n)이기 때문입니다. 초기 로드가 아닌 상호 작용 시 지연 로드가 필요합니다.


What’s the solution?
Qwik은 JavaScript를 적게 만드는 것이 아닙니다. Qwik은 애플리케이션 시작 시 모든 JavaScript를 한 번에 클라이언트에 제공할 필요가 없다는 것입니다. Qwik은 JavaScript의 지연 로드를 극단적으로 생각했을 때 얻게 되는 것입니다.
사용자 상호 작용을 기반으로 하는 점진적 JavaScript 다운로드를 통해 초기 JavaScript는 거의 0에 가깝습니다.


Resumable vs. Hydration
SSR/SSG 애플리케이션이 클라이언트에서 부팅될 때 클라이언트의 프레임워크는 다음 세 가지 정보를 복원해야 합니다.
- Listeners — 이벤트 리스너를 찾아 DOM 노드에 설치하여 응용 프로그램을 대화형으로 만듭니다.
- Component tree — 애플리케이션 컴포넌트 트리를 나타내는 내부 데이터 구조를 구축
- Application state — 애플리케이션 상태를 복원
이것을 hydration(수화)이라고 하고 모든 현재 세대의 프레임워크는 애프리케이션을 인터랙티브로 만들기 위해 이 단계가 필요합니다.
수화 두 가지 이유로 비용이 많이 듭니다.
- 현재 페이지와 연결된 모든 컴포넌트 코드를 다운로드해야 합니다.
- 프레임워크는 리스너 위치와 내부 구성 요소 트리를 다시 빌드하기 위해 페이지의 컴포넌트와 연결된 템플릿을 실행해야 합니다.



다른 모든 프레임워크의 수화는 클라이언트의 모든 애플리케이션 로직을 재생합니다.
Qwik은 수화 작업이 필요 없기 때문에 즉시 시작합니다.
Resumability
Qwik은 대신 서버에서 실행을 일시 중지하고 클라이언트에서 실행을 재개합니다. 이를 달성하기 위해 3가지 문제(리스너, 구성 요소 트리, 애플리케이션 상태)를 해결해야 합니다.
Listeners
기존 프레임워크는 컴포넌트를 다운로드하고 템플릿을 실행하여 이벤트 리스너를 수집한 다음 DOM에 연결하여 이벤트 리스너를 해결합니다. 현재 접근 방식에는 다음과 같은 문제가 있습니다.
- 템플릿 코드가 빠르게 다운로드 필요
- 템플릿 코드가 빠르게 실행될 필요
- 이벤트 핸들러가 빠르게 다운로드되고 연결될 필요
응용 프로그램이 복잡해짐에 따라 다운로드하고 실행하는 데 필요한 코드의 양이 응용 프로그램의 크기에 비례하여 늘어납니다. 이는 응용 프로그램 시작 성능과 사용자 경험에 부정적인 영향을 미칩니다.
Qwik은 이벤트 수신을 다음과 같이 DOM에 직렬화하여 위의 문제를 해결합니다.
<button on:click="./chunk.js#handler_symbol">click me</button>
on:click 속성에는 애플리케이션을 재개할 수 있는 모든 정보가 포함되어 있습니다.
- Qwikloader는 글로벌 리스너를 설정합니다. 이 단계는 애플리케이션 코드가 없어도 수행할 수 있습니다.
- HTML에는 청크 및 심볼 이름에 대한 URL이 포함되어 있습니다. 이 속성은 Qwikloader에 다운로드할 코드 청크와 청크에서 검색할 심볼을 알려줍니다.
- Qwik의 이벤트 처리 구현은 비동기식 지연 로딩으로 삽입합니다.
Demo
https://qwik.builder.io/examples/reactivity/counter/
Component Trees
프레임워크는 컴포넌트 트리와 함께 작동합니다. 이를 위해 프레임워크는 어떤 컴포넌트를 언제 다시 렌더링해야 하는지 알기 위해 컴포넌트 트리를 완전히 이해해야 합니다.
이 정보를 재생성하기 위해 프레임워크는 컴포넌트 템플릿을 다시 실행하고 컴포넌트 경계 위치(boundary location)를 메모합니다. 재실행(Re-execution)이 바로 수분(hydration)입니다. 수화는컴포넌트 템플릿의 다운로드와 실행이 모두 필요하므로 비용이 많이 듭니다.
Qwik은 SSR/SSG의 일부로 컴포넌트 경계 정보를 수집한 다음 해당 정보를 HTML로 직렬화합니다. 그 결과 Qwik은 다음을 수행할 수 있습니다.
- 컴포넌트 코드가 지연될 수 있습니다.
- 다시 렌더링해야 하는 구성 요소에 대해서만 지연 작업을 수행할 수 있습니다.
- 스토어과 컴포넌트 간의 관계 정보를 수집합니다. 이렇게 하면 상태 변경의 결과로 다시 렌더링해야 하는 구성 요소를 Qwik에 알리는 구독 모델이 생성됩니다. 구독 모델에 대한 구독 정보도 HTML로 직렬화됩니다.
Compare render process




Application State
Qwik에는 구성 요소의 수명 주기에 더 긴밀하게 통합된 상태 관리가 있습니다. 컴포넌트 props는 일반적으로 상위 컴포넌트에 의해 생성되기 때문에 기존 프레임워크에서는 쉽게 달성할 수 없습니다. 이것은 연쇄 반응을 생성합니다. 컴포넌트 X를 복원하려면 상위 요소도 복원해야 합니다. Qwik을 사용하면 상위 컴포넌트 코드가 없는 상태에서 모든 구성 요소를 재개할 수 있습니다.
Progressive
점진적으로 전체 코드베이스를 열심히 다운로드할 필요 없이 애플리케이션이 필요로 하는 대로 코드를 다운로드하는 것입니다.
이것은 가능한 한 오랫동안 JavaScript의 로드 및 실행을 지연시키는 데 중점을 둔 Qwik의 핵심이며 이를 달성하기 위해 애플리케이션을 지연 로드 가능한 많은 청크로 분할해야 합니다.
Qwik Optimizer은 컴포넌트를 청크로 분할하고 필요에 따라 다운로드합니다. 그리고 프레임워크 런타임은 컴포넌트가 렌더 트리의 일부인 경우에도 상호 작용에 필요하지 않은 코드를 다운로드할 필요가 없습니다.
Qwik에서는 모든 것이 지연 로드 가능합니다.
- Component on-render(초기화 블록 및 렌더 블록)
- Component on-watch(부작용(side-effects), 입력이 변경된 경우에만 다운로드됨)
- Listeners(상호작용 시에만 다운로드)
- Styles(서버에서 아직 제공하지 않은 경우에만 다운로드됨)
Prefetching
애플리케이션이 백그라운드 작업에서 모듈 다운로드를 시작하는 방법입니다.
예를 들어, 제품 페이지에는 “장바구니에 추가” 버튼에 대한 클릭 리스너가 있을 수 있으며 이 버튼을 클릭하면 사용자는 즉시 장바구니에 추가된 제품을 보여주는 피드백을 받아야 합니다. 이 예에서 Qwik은 전체 애플리케이션 또는 경로에 대한 모든 JavaScript가 아니라 이벤트 리스너에 대한 코드만 미리 가져올 수 있습니다.
재개 가능성(Resumability)과 수화(Hydration) 기능의 차이점은 이벤트 리스너, 컴포넌트 트리 및 애플리케이션 상태를 복원하기 위해 JavaScript 실행을 피할 수 있다는 점입니다. 컴포넌트의 이벤트 리스너, 렌더링 기능 및 상태를 근본적으로 분리함으로써 프리페치할 코드의 양이 기존 접근 방식보다 훨씬 적습니다.
Conclusion
번들링의 진화와 함께 프론트엔드의 프레임워크도 함께 진화하고 있습니다.
이제 다음 세대의 번들러와 프레임워크가 나오고 있습니다.
1년마다 새로운 아이디에이션을 통한 제품과 솔루션, 아키텍처가 나오고 있는 프론트엔드 기술에 화이팅 입니다.


Reference
https://www.builder.io/blog/dont-blame-the-developer-for-what-the-frameworks-did
https://www.builder.io/blog/our-current-frameworks-are-on-we-need-o1