[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
---
|
||||
id: frontend-solid-qwik-deep
|
||||
title: SolidJS / Qwik — signal-based reactivity
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [frontend, solid, qwik, vibe-coding]
|
||||
tech_stack: { language: "TS", applicable_to: ["Frontend"] }
|
||||
applied_in: []
|
||||
aliases: [SolidJS, Qwik, signals, fine-grained reactivity, resumability, no VDOM]
|
||||
---
|
||||
|
||||
# SolidJS / Qwik
|
||||
|
||||
> React 의 future. **Solid (signal, no VDOM), Qwik (resumability, 0 hydration)**. Modern reactivity primitive.
|
||||
|
||||
## 📖 핵심 개념
|
||||
- Signal: reactive primitive.
|
||||
- Solid: compile-time + signals.
|
||||
- Qwik: lazy hydrate (resumability).
|
||||
- React Compiler 가 비슷 path.
|
||||
|
||||
## 💻 코드 패턴
|
||||
|
||||
### Solid
|
||||
```tsx
|
||||
import { createSignal, createEffect } from 'solid-js';
|
||||
|
||||
function Counter() {
|
||||
const [count, setCount] = createSignal(0);
|
||||
|
||||
createEffect(() => {
|
||||
console.log('count:', count());
|
||||
});
|
||||
|
||||
return <button onClick={() => setCount(count() + 1)}>{count()}</button>;
|
||||
}
|
||||
```
|
||||
|
||||
→ `count()` 가 function. Component 가 1번 만 (no re-render).
|
||||
|
||||
### Solid 의 signal
|
||||
```ts
|
||||
const [name, setName] = createSignal('Alice');
|
||||
console.log(name()); // 'Alice'
|
||||
setName('Bob');
|
||||
console.log(name()); // 'Bob'
|
||||
```
|
||||
|
||||
→ Get / set primitive.
|
||||
|
||||
### Effect / memo
|
||||
```tsx
|
||||
const double = createMemo(() => count() * 2);
|
||||
// → cached, signal 변경 시만 재계산.
|
||||
|
||||
createEffect(() => {
|
||||
console.log('double:', double());
|
||||
});
|
||||
```
|
||||
|
||||
→ React 의 useMemo / useEffect 비슷.
|
||||
|
||||
### Resource (async)
|
||||
```tsx
|
||||
const [user] = createResource(userId, fetchUser);
|
||||
|
||||
return <p>{user()?.name}</p>;
|
||||
```
|
||||
|
||||
→ Suspense 친화.
|
||||
|
||||
### Solid 의 "no VDOM"
|
||||
```
|
||||
React: 매 render = VDOM diff.
|
||||
Solid: 매 signal 변경 = 정확 DOM 부분 update.
|
||||
|
||||
→ "Most efficient" benchmark.
|
||||
```
|
||||
|
||||
### Solid Start (fullstack)
|
||||
```tsx
|
||||
// routes/index.tsx
|
||||
export default function Home() {
|
||||
const [count, setCount] = createSignal(0);
|
||||
return <button onClick={() => setCount(count() + 1)}>{count()}</button>;
|
||||
}
|
||||
```
|
||||
|
||||
→ Next.js 의 Solid version.
|
||||
|
||||
### Qwik
|
||||
```tsx
|
||||
import { component$, useSignal } from '@builder.io/qwik';
|
||||
|
||||
export default component$(() => {
|
||||
const count = useSignal(0);
|
||||
|
||||
return (
|
||||
<button onClick$={() => count.value++}>
|
||||
{count.value}
|
||||
</button>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
→ `$` = lazy boundary. JS 가 lazy load.
|
||||
|
||||
### Qwik 의 resumability
|
||||
```
|
||||
React:
|
||||
- Server render HTML.
|
||||
- Client hydrate (모든 JS).
|
||||
- "Hydration cost" = 큰.
|
||||
|
||||
Qwik:
|
||||
- Server render HTML + state.
|
||||
- Client = 0 JS download (idle).
|
||||
- Click 시 = 그 click handler 의 JS 만 download.
|
||||
|
||||
→ 큰 page = 매우 빠름 first interaction.
|
||||
```
|
||||
|
||||
### Qwik City (fullstack)
|
||||
```tsx
|
||||
// routes/index.tsx
|
||||
import { component$ } from '@builder.io/qwik';
|
||||
|
||||
export default component$(() => {
|
||||
return <h1>Hello</h1>;
|
||||
});
|
||||
|
||||
// Server route
|
||||
export const onGet: RequestHandler = async ({ json }) => {
|
||||
json(200, { msg: 'API' });
|
||||
};
|
||||
```
|
||||
|
||||
### vs React
|
||||
```
|
||||
React:
|
||||
- VDOM + reconciliation.
|
||||
- React Compiler 가 자동 memo (modern).
|
||||
- 큰 ecosystem.
|
||||
|
||||
Solid:
|
||||
- No VDOM.
|
||||
- 매우 빠름.
|
||||
- 작은 ecosystem.
|
||||
|
||||
Qwik:
|
||||
- Resumability.
|
||||
- 0 hydration cost.
|
||||
- Steeper learning.
|
||||
```
|
||||
|
||||
### Signals 의 evolution
|
||||
```
|
||||
1. Knockout / RxJS (옛 reactive).
|
||||
2. Vue / Angular (자체 signal).
|
||||
3. SolidJS (modern primitive).
|
||||
4. Preact signals.
|
||||
5. Svelte 5 (rune).
|
||||
6. React Compiler (대신 자동 memo).
|
||||
```
|
||||
|
||||
→ Signal 가 수렴.
|
||||
|
||||
### Use case
|
||||
```
|
||||
Solid:
|
||||
- Performance critical (data viz, real-time).
|
||||
- Small bundle (작은 lib).
|
||||
- React 비슷 API 가 좋음.
|
||||
|
||||
Qwik:
|
||||
- E-commerce (Shopify Hydrogen 의 alternative).
|
||||
- Marketing site (FCP critical).
|
||||
- 큰 page + 적은 interaction.
|
||||
```
|
||||
|
||||
### When NOT?
|
||||
```
|
||||
- 큰 React ecosystem 에 의존.
|
||||
- Library 가 React-only.
|
||||
- Team 가 React 만 알아.
|
||||
- Migration cost 큰.
|
||||
```
|
||||
|
||||
→ React + Compiler 가 수렴.
|
||||
|
||||
### Migration Solid (React 에서)
|
||||
```tsx
|
||||
// React
|
||||
const [count, setCount] = useState(0);
|
||||
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
|
||||
|
||||
// Solid
|
||||
const [count, setCount] = createSignal(0);
|
||||
return <button onClick={() => setCount(count() + 1)}>{count()}</button>;
|
||||
```
|
||||
|
||||
→ 거의 같음. Function call vs property.
|
||||
|
||||
### Solid devtools
|
||||
```
|
||||
Browser extension.
|
||||
- Component tree.
|
||||
- Signal state.
|
||||
- 매 effect 의 trigger.
|
||||
```
|
||||
|
||||
### Production
|
||||
```
|
||||
Solid:
|
||||
- Small but growing.
|
||||
- Babylon.js 의 demo.
|
||||
- 작은 / specific app.
|
||||
|
||||
Qwik:
|
||||
- Builder.io (자체).
|
||||
- Some Shopify e-commerce.
|
||||
```
|
||||
|
||||
### 함정 (Solid)
|
||||
```
|
||||
- `count` vs `count()`: function call 잊음.
|
||||
- Destructure: signal 가 lose reactivity.
|
||||
- For each + signal: createSignal 안에서 lifecycle.
|
||||
```
|
||||
|
||||
```tsx
|
||||
// ❌
|
||||
const { count, setCount } = state; // destructure → 잃음.
|
||||
|
||||
// ✅ accessor
|
||||
return <p>{state.count()}</p>;
|
||||
```
|
||||
|
||||
### Future
|
||||
```
|
||||
2026: Solid 가 niche, React Compiler 가 mainstream.
|
||||
Qwik 가 specific (e-commerce).
|
||||
React + Compiler 가 가장 큰 user base.
|
||||
|
||||
→ "Best framework" debate 가 지난.
|
||||
"Use what works" 가 답.
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준
|
||||
| 상황 | 추천 |
|
||||
|---|---|
|
||||
| Performance critical | Solid |
|
||||
| 0 hydration cost | Qwik |
|
||||
| 큰 ecosystem | React + Compiler |
|
||||
| Migration | React stay |
|
||||
| New small project | Solid 시도 |
|
||||
| E-commerce | Qwik / Astro |
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Signal destructure**: lose reactivity.
|
||||
- **Solid + React patterns 가정**: 다름.
|
||||
- **모든 거 reactive**: 가짜 dependency.
|
||||
- **Qwik + heavy interaction**: hydration cost.
|
||||
- **Bundle size 강조 + library 큰**: trade-off.
|
||||
|
||||
## 🤖 LLM 활용 힌트
|
||||
- Signal 가 modern reactivity.
|
||||
- React Compiler 가 React 의 답.
|
||||
- Solid 가 niche / specific.
|
||||
- Qwik 가 e-commerce 친화.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[Frontend_SolidJS_Qwik]]
|
||||
- [[Frontend_React_Compiler_Deep]]
|
||||
- [[Frontend_Million_Optimization]]
|
||||
Reference in New Issue
Block a user