Qwik Resumability
Qwik Resumability Interview Framework Hydration Lazy Loading Serialization QwikCity Performance Lighthouse TTI E-commerce Production
| Feature | Qwik | React/Next.js | Astro | SolidJS |
|---|---|---|---|---|
| Rendering | Resumability | Hydration | Islands | Fine-grained |
| Initial JS | ~1KB | ~80-200KB | ~0KB static | ~10-30KB |
| TTI | Near instant | 1-5s (app size) | Near instant | Fast |
| State Mgmt | useSignal useStore | useState Redux | Framework-specific | createSignal |
| Routing | QwikCity | Next.js App Router | File-based | SolidStart |
| Learning | ปานกลาง | ง่าย (mature) | ง่าย | ปานกลาง |
| Ecosystem | Growing | ใหญ่มาก | Growing | เล็ก |
Core Concepts
# === Qwik Core Concepts ===
# Component with $ (Lazy Loading Boundary)
# import { component$, useSignal } from '@builder.io/qwik';
#
# export const Counter = component$(() => {
# const count = useSignal(0);
#
# return (
# <div>
# <p>Count: {count.value}</p>
# <button onClick$={() => count.value++}>
# Increment
# </button>
# </div>
# );
# });
# useSignal — Reactive primitive
# const name = useSignal(''); // Simple reactive value
# name.value = 'Qwik'; // Update triggers re-render
# useStore — Reactive object
# const state = useStore({
# items: [],
# loading: false,
# error: null,
# });
# state.loading = true; // Deep reactive
# useTask$ — Side effects (like useEffect)
# useTask$(({ track }) => {
# track(() => count.value);
# console.log('Count changed:', count.value);
# });
# useVisibleTask$ — Client-only task
# useVisibleTask$(() => {
# // Runs only in browser, when component is visible
# const chart = new Chart(canvasRef.value, config);
# });
from dataclasses import dataclass
@dataclass
class QwikConcept:
concept: str
syntax: str
react_equivalent: str
purpose: str
lazy: bool
concepts = [
QwikConcept("component$", "component$(() => JSX)", "function Component()", "Define component with lazy boundary", True),
QwikConcept("useSignal", "useSignal(initial)", "useState(initial)", "Simple reactive value", False),
QwikConcept("useStore", "useStore({...})", "useState({...}) or Redux", "Reactive object/array", False),
QwikConcept("onClick$", "onClick$={() => ...}", "onClick={() => ...}", "Event handler with lazy loading", True),
QwikConcept("useTask$", "useTask$(({track}) => ...)", "useEffect(() => ...)", "Side effect on server+client", True),
QwikConcept("useVisibleTask$", "useVisibleTask$(() => ...)", "useEffect (client only)", "Client-only when visible", True),
QwikConcept("routeLoader$", "routeLoader$(() => fetch)", "getServerSideProps", "Server data loading", True),
QwikConcept("routeAction$", "routeAction$(() => ...)", "Server Actions", "Form handling server-side", True),
]
print("=== Qwik Concepts ===")
for c in concepts:
lazy = "LAZY $" if c.lazy else "Eager"
print(f" [{c.concept}] {lazy}")
print(f" Syntax: {c.syntax}")
print(f" React: {c.react_equivalent}")
print(f" Purpose: {c.purpose}")
Interview Questions
# === Qwik Interview Questions ===
@dataclass
class InterviewQ:
question: str
difficulty: str
key_points: str
common_mistake: str
questions = [
InterviewQ("Resumability คืออะไร ต่างจาก Hydration อย่างไร",
"Medium",
"Serialize state+listeners ใน HTML, ไม่ re-execute, O(1) vs O(n)",
"บอกว่า Qwik ไม่ใช้ JS เลย (ใช้แต่ lazy load)"),
InterviewQ("$ suffix ใน Qwik หมายความว่าอะไร",
"Medium",
"Lazy loading boundary, optimizer แยกเป็น chunk, โหลดเมื่อต้องใช้",
"คิดว่าเป็นแค่ naming convention ไม่ใช่ functional"),
InterviewQ("useSignal กับ useStore ต่างกันอย่างไร",
"Easy",
"Signal = primitive value, Store = reactive object/array, Store deep reactive",
"ใช้ Store สำหรับทุกอย่าง ทั้งที่ Signal เพียงพอ"),
InterviewQ("อธิบาย Serialization ใน Qwik",
"Hard",
"State serialized เป็น JSON ใน HTML attribute, ไม่ต้อง hydrate, resume ได้ทันที",
"ไม่รู้ว่า Closure ก็ serialize ได้ด้วย"),
InterviewQ("QwikCity routeLoader$ ทำงานอย่างไร",
"Medium",
"Run on server, return data, available in component via useRouteLoader$",
"สับสนกับ routeAction$ ซึ่งสำหรับ mutation"),
InterviewQ("Qwik เหมาะกับ Use Case ไหน",
"Easy",
"E-commerce, content sites, apps ที่ต้อง fast TTI, SEO important",
"บอกว่าเหมาะทุกอย่าง ไม่พูดถึง trade-offs เช่น ecosystem เล็ก"),
InterviewQ("Trade-offs ของ Qwik มีอะไร",
"Hard",
"Ecosystem เล็ก, mental model ใหม่, $ syntax, community เล็กกว่า React",
"บอกว่าไม่มี trade-offs"),
]
print("=== Interview Questions ===")
for q in questions:
print(f" [{q.difficulty}] {q.question}")
print(f" Key: {q.key_points}")
print(f" Avoid: {q.common_mistake}")
Performance Comparison
# === Performance Benchmark ===
@dataclass
class PerfBenchmark:
framework: str
initial_js_kb: float
tti_ms: int
lcp_ms: int
lighthouse: int
build_time_s: int
benchmarks = [
PerfBenchmark("Qwik + QwikCity", 1.2, 200, 800, 99, 15),
PerfBenchmark("Next.js (App Router)", 85, 1800, 1200, 88, 25),
PerfBenchmark("Astro (Static)", 0, 150, 600, 100, 10),
PerfBenchmark("Astro + React Islands", 25, 800, 900, 95, 12),
PerfBenchmark("SolidStart", 12, 500, 850, 96, 8),
PerfBenchmark("Nuxt 3", 65, 1500, 1100, 90, 20),
]
print("=== Performance Comparison ===")
for b in benchmarks:
print(f" [{b.framework}]")
print(f" JS: {b.initial_js_kb}KB | TTI: {b.tti_ms}ms | LCP: {b.lcp_ms}ms")
print(f" Lighthouse: {b.lighthouse} | Build: {b.build_time_s}s")
# Interview Prep Checklist
prep = {
"Concept": "Resumability, $, Serialization, Signals, QwikCity",
"Code": "Build a Todo app or E-commerce page with Qwik",
"Compare": "Qwik vs React/Next.js — pros, cons, trade-offs",
"Performance": "Run Lighthouse, compare scores, explain why",
"Deploy": "Deploy to Vercel or Cloudflare, show live demo",
"Questions": "Prepare 5 questions to ask interviewer about their Qwik usage",
}
print(f"\n\nInterview Prep Checklist:")
for k, v in prep.items():
print(f" [{k}]: {v}")
เคล็ดลับ
- $: เข้าใจ $ suffix เป็น Lazy Loading Boundary สำคัญที่สุด
- Resume: อธิบาย Resumability vs Hydration ได้ชัดเจน
- Demo: สร้าง Demo Project แสดง Lighthouse Score
- Trade-offs: พูดถึงข้อดีและข้อเสียอย่างตรงไปตรงมา
- Compare: เปรียบเทียบกับ React/Next.js อย่างเป็นธรรม
Qwik Resumability คืออะไร
Frontend Framework Resumability แทน Hydration Serialize State HTML User Interact โหลด JS เฉพาะส่วน Initial Load เร็ว Lighthouse E-commerce Content
Resumability ต่างจาก Hydration อย่างไร
Hydration โหลด JS ทั้งหมด Re-execute Component O(n) Resumability Serialize State Listener HTML ไม่ Re-execute โหลดเฉพาะส่วน O(1)
QwikCity คืออะไร
Meta-framework Qwik เหมือน Next.js File-based Routing Layout routeLoader$ Data routeAction$ Form Middleware SSR SSG Hybrid Vercel Cloudflare
เตรียมสัมภาษณ์ Qwik อย่างไร
Resumability vs Hydration $ suffix Lazy Boundary Serialization QwikCity Demo Project Lighthouse Compare React Trade-offs Ecosystem
สรุป
Qwik Resumability Interview Hydration Lazy Loading $ Serialization QwikCity routeLoader$ Performance Lighthouse E-commerce Production Deployment
