Refactor: Consolidate directory structure into 5 main categories and update metadata

This commit is contained in:
Antigravity Agent
2026-05-02 23:17:19 +09:00
parent 87fa983521
commit b71a0b82d3
13205 changed files with 114378 additions and 201654 deletions
@@ -1,125 +0,0 @@
# Skybound Code Structure Audit and Stabilization Plan
**Date**: 2026-04-24
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Raw [[Analysis|Analysis]] logged before implementation
## 1. Overview
This document records the first code-level audit after reviewing Skybound-related wiki documents. The [[goal|goal]] was to compare the documented [[Architecture|Architecture]] with the actual code path in `/Volumes/Data/project/Antigravity/Skybound`, identify design and feature risks, and define the first stabilization pass.
## 2. Documents Reviewed
- `Topics/Skybound/[[Skybound-Knowledge-Hub|Skybound-Knowledge-Hub]].md`
- `Topics/Skybound/01_Core_Engine/[[Skybound-Modular-Game-Architecture|Skybound-Modular-Game-Architecture]].md`
- `Topics/Skybound/01_Core_Engine/[[Game-Engine-Loop-and-System-Orchestration|Game-Engine-Loop-and-System-Orchestration]].md`
- `Topics/Skybound/05_Project_Issues/2026-04-22_Engine_Stability_Audit.md`
- `Topics/Skybound/02_Combat_AI/[[Combat-System-and-Bullet-Interaction-Pipeline|Combat-System-and-Bullet-Interaction-Pipeline]].md`
- `Topics/Skybound/04_Mechanics_Progression/Campaign_and_Dual_Loop[[_system|_system]].md`
- `Topics/Skybound/04_Mechanics_Progression/[[InGame_Progression_System|InGame_Progression_System]].md`
- `Technical_[[Reports|Reports]]/2026-04-22_Boss_Battle_System_Implementation.md`
## 3. Code Structure [[Observation|Observation]]s
Skybound's actual runtime center is `src/features/game/hooks/useGameEngine.ts`. It directly instantiates and updates `EntityManager`, `StageDirectorSystem`, `SpawnerSystem`, `CombatSystem`, `ProgressionSystem`, `ModularWeaponSystem`, `TacticalSystem`, `HazardSystem`, `BossSystem`, `EffectSystem`, and `GameRenderer`.
`SystemManager.ts` exists and documents a centralized orchestration pattern, but the active engine path does not use it. This is not inherently broken, but it creates a mismatch between the documented orchestrator and the actual execution path.
React is primarily responsible for scene composition and modal/UI handling through `GameSceneRenderer.tsx`, while Zustand [[State|State]] is centralized in `useGameStore.ts`.
## 4. Confirmed Problems
### 4.1 Build Gate Is Broken
`npm run build` fails. Representative causes:
- `App.tsx` imports `useGameEngine` but does not use it.
- Legacy `src/features/game/combatSystem.ts` is still included in TypeScript compilation and has type drift against current domain models.
- `useSceneAudio.ts` does not include `HANGAR` in `SCENE_AUDIO`, despite `Scene` including `HANGAR`.
- `SystemBoss.phase` is typed as `1 | 2 | 3`, while `bossRegistry.ts` contains a 4-phase boss.
- `GameRenderer.ts` calls `CanvasRenderingContext2D.close()`, which should be `closePath()`.
- `EntityManager` initializes enemies with `movePattern: 'NONE'`, which is not part of the current `Enemy.movePattern` union.
### 4.2 Timeline Spawn Intents Are Not Wired
`StageDirectorSystem` dispatches `SCRIPTED_SPAWN` and `SPAWN_MODE` intents, but `useGameEngine.ts` does not route those intents to `SpawnerSystem`.
`SpawnerSystem` already provides `notifyScriptedSpawn()` and `activateSwarmBurst()`, so the design exists but the active dispatch wiring is missing.
Expected impact: scripted waves and burst [[Events|Events]] may not appear as designed, leaving procedural spawning to carry too much of the combat pacing.
### 4.3 Campaign Stage State Is Not a [[Single_Source_of_Truth|Single Source of Truth]]
`StageDirectorSystem` receives `campaignStageIndex` when created, but `GameState.currentStage` still defaults to `1` and is not initialized from the selected campaign stage.
Expected impact: Standard campaign can show stage progression in UI while the engine continues to evaluate boss selection, damage curves, backgrounds, rewards, and tech-part rolls as Stage 1.
### 4.4 StageManager Mode Can Drift from Store Mode
`StageManager` has its own internal `mode`, defaulting to `BLITZ`. The UI updates Zustand `stageMode`, but `stageManager.setMode()` is not called from the store action.
Expected impact: Standard campaign clear can call `stageManager.onStageClear()` while the singleton still believes it is in Blitz mode, preventing next-stage campaign progression.
### 4.5 COMMS Events Are Not Rendered
`COMMS` events are emitted by engineSystems, and `CommsOverlay.tsx` exists, but `useGameEngine.ts` does not map `COMMS` events to `useGameStore.setComms()`. `CommsOverlay` is also not rendered by `App.tsx`.
Expected impact: mission dialogue, warning text, and tactical pacing messages are silently dropped.
### 4.6 Starter Weapon Timer Is Not Cleaned Up
`useGameEngine.ts` st[[Arts|Arts]] a `setTimeout()` for starter weapon selection, but cleanup does not clear the timer.
Expected impact: if the engine unmounts quickly, a stale timer can emit a level-up modal or pause signal from an old engine instance.
### 4.7 Skill Sync Boundary Is Fragile
`GameSceneRenderer.tsx` calls store `addSkill()` and then engine `applySkill()`. `ProgressionSystem.applySkillSelection()` says Zustand owns skill increments, but also mutates `state.skills` as a fallback.
Expected impact: this usually works because of the store subscription bridge, but the ownership boundary is not clean and may cause missed or inconsistent skill levels under timing stress.
## 5. Stabilization Plan
Priority order:
1. Restore TypeScript build by removing obvious compile blockers and isolating legacy drift.
2. Wire `SCRIPTED_SPAWN` and `SPAWN_MODE` intents from `StageDirectorSystem` into `SpawnerSystem`.
3. Initialize engine `currentStage` from `stageMode` and `campaignStageIndex`.
4. Keep `StageManager` mode synchronized with Zustand `stageMode`.
5. Route `COMMS` events into the store and render `CommsOverlay`.
6. Clear the starter weapon timer during engine cleanup.
## 6. Verification Targets
- `npm run build`
- `npm run lint` as a visibility check, with the expectation that broad historical lint debt may remain after the first stabilization pass.
## 7. Implementation Result
The first stabilization pass was applied immediately after this raw audit.
### 7.1 Build Recovery
- Removed an unused `useGameEngine` import from `App.tsx`.
- Added `HANGAR` to `SCENE_AUDIO` in `useSceneAudio.ts`.
- Excluded legacy `src/features/game/combatSystem.ts` from `tsconfig.app.json` because the active runtime path uses `src/features/game/systems/CombatSystem.ts`.
- Expanded boss phase typing from `1 | 2 | 3` to `number` so 4-phase registry bosses are valid.
- Fixed `EntityManager` default enemy `movePattern` from invalid `NONE` to `SIDE_TO_SIDE`.
- Fixed `CanvasRenderingContext2D.close()` to `closePath()`.
- Removed compile-[[Blocking|Blocking]] unused locals from active systems.
### 7.2 Runtime Wiring Recovery
- `SCRIPTED_SPAWN` intents now call `SpawnerSystem.notifyScriptedSpawn()`.
- `SPAWN_MODE` intents now activate `SWARM_BURST` or enqueue `MINI_BOSS` spawns.
- Engine `currentStage` now initializes from `campaignStageIndex + 1` in Standard mode.
- Zustand `setStageMode()` now synchronizes the `StageManager` singleton mode.
- `COMMS` engine events now populate `useGameStore.activeComms`.
- `CommsOverlay` is rendered while playing.
- Starter weapon selection timer is cleared during engine cleanup.
### 7.3 Verification Result
- `npm run build`: passed.
- `npm run lint`: still fails due broad pre-existing lint debt, mostly `@typescript-[[ESLint|ESLint]]/no-explicit-any`, older helper files, and React hook lint findings. The first pass reduced the functional blockers but did not attempt a large-scale type cleanup.
@@ -1,149 +0,0 @@
# Skybound Final Stylized Casual Magitech Redirection
**Date**: 2026-04-24
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Raw art direction correction after final concept change
## 1. Reason for Redirection
The previous pass moved Skybound toward **Semirealistic Magitech Fantasy**, but the latest direction returns the project to a clearer and more immediately readable mobile-survival style.
The new target is **Stylized Casual Magitech** for a top-down survival shooter inspired by Survivor.io.
This direction prioritizes:
- maximum in-game visibility
- bold silhouettes
- thick readable outlines
- flat lighting
- vivid magical accents
- consistent UI language from intro to mission result
## 2. Core Concept
Skybound should feel like a polished casual magitech action game rather than a dark semirealistic fantasy title.
Primary gameplay readability goals:
- player vehicle must be instantly identifiable
- enemies must remain readable in dense hordes
- pickups and weapon icons must be recognizable at small sizes
- background grid must [[Support|Support]] movement clarity without competing with combat
- every exposed screen should share the same playful magitech frame language
## 3. Tone and Manner
### Stylized Casual Magitech
Visual language:
- bold navy outlines
- clean top-down silhouettes
- flat color blocks
- minimal material [[Noise|Noise]]
- bright arcane cyan
- gold/orange mechanical accents
- purple and pink enemy/corruption accents
- chunky UI frames
- high contrast buttons and progress bars
Avoid:
- [[Grit|Grit]]ty brushed [[Metal|Metal]]
- heavy realistic shadows
- low-contrast dark UI
- thin semireal linework
- noisy texture detail
- external non-project image dependencies
## 4. Palette
Base colors:
- deep navy outline
- saturated royal blue panels
- readable sapphire floor tiles
- bright brass and gold trim
Magic accents:
- arcane cyan for player and positive energy
- crystal white-blue for highlights
- vivid purple for advanced magic
- hot pink for danger and enemy cores
- mint green for healing and positive pickups
- orange/gold for calls to action
## 5. Screen Coverage
The exposed user-facing screens were reviewed and targeted by the final theme pass:
- Intro title screen
- Airframe select screen
- Hangar / upgrade overlay
- In-game HUD
- Quick start overlay
- Tutorial overlay
- Comms overlay
- Level up modal
- Mission success / failed / complete result screen
## 6. Asset Coverage
The procedural asset generator now outputs the final Stylized Casual Magitech library while preserving runtime file paths.
Generated categories:
- Magitech player airframes
- normal enemies
- elite enemies
- bosses
- modular stage tiles
- title and result local backdrops
- item drop sprite sheet
- turret sheet
- weapon and skill icons
- projectiles
- shield and currency icons
- muzzle flash, impact, explosion, and laser VFX
- commander and pilot portraits
- contact sheet preview
## 7. Implementation Notes
The generator was redirected away from semirealistic material rendering and toward flat, readable shapes.
Main implementation choices:
- palette updated to bright casual magitech colors
- default shape helpers now draw bold navy outlines
- material texture strength reduced to keep assets flat
- background tiles use readable grid blocks and low-competition arcane circuitry
- local title and result background images were generated
- title and result screens no longer depend on external Google image URLs
- global magitech CSS override was rewritten for the final casual tone
## 8. Changed Runtime Paths
Important changed or generated paths:
- `/Volumes/Data/project/Antigravity/Skybound/[[Scripts|Scripts]]/generate_magitech_assets.py`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/styles/magitechArt.css`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/TitleScreen.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/ResultCard.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/magitech_art_contact_sheet.png`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/background/title_magitech.png`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/background/result_magitech.png`
## 9. Verification
Asset generation completed successfully.
Production build completed successfully with:
```bash
npm run build
```
The build still [[Reports|Reports]] that `/sprites/player.png` is left unresolved at build time, which is a Vite static asset warning and was already non-[[Blocking|Blocking]]. The production bundle was generated successfully.
@@ -1,74 +0,0 @@
# Skybound HUD and TAC Level Up Stylized Casual Magitech Fix
**Date**: 2026-04-24
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Raw follow-up fix from gameplay HUD screenshot review
## 1. Screenshot Issues
The reviewed gameplay screenshots showed that the HUD and TAC Level Up modal still leaned heavily into the previous cyber-terminal style.
Observed issues:
- side HUD panels used thin cyan lines and transparent glass styling
- top TAC level widget looked like a cold terminal module
- control buttons were dark mono[[Chrome|Chrome]] blocks
- TAC Level Up modal used glitch text and blue terminal cards
- skill cards did not share the bold casual magitech frame language
## 2. Cause
The global `magitechArt.css` provided the broad art direction, but component-level CSS files still applied later or more specific styles.
Main affected files:
- `HUDOverlay.css`
- `LevelUpModal.css`
These files preserved the original Stitch/cyber UI look and overrode p[[Arts|Arts]] of the new tone.
## 3. Fixes Applied
### HUD
HUD styling was redirected to Stylized Casual Magitech:
- chunky navy outlines
- rounded blue magitech panels
- gold active highlights
- mint/cyan resource bars
- less transparent glass
- stronger mobile-game button [[Affordance|Affordance]]
- side modules grouped into readable cards
- top TAC level widget converted to a framed casual panel
### TAC Level Up Modal
The level-up modal was restyled:
- removed glitch pseudo text
- removed aggressive terminal skew animation
- converted the modal into a rounded blue magitech reward panel
- added thick dark outline and drop-shadow depth
- changed skill cards to chunky selectable cards
- changed icon boxes to framed magitech sockets
- converted level dots into brighter readable pips
- kept EVO cards gold/orange for special hierarchy
## 4. Changed Runtime Paths
Important changed paths:
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/HUDOverlay.css`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/LevelUpModal.css`
## 5. Verification
Production build completed successfully with:
```bash
npm run build
```
The existing `/sprites/player.png` static path warning remains non-[[Blocking|Blocking]].
@@ -1,83 +0,0 @@
# Skybound Nova Burst Icon and Effect Fix
**Date**: 2026-04-24
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Raw follow-up fix for skill-specific visual mismatch
## 1. Screenshot Issue
`Nova Burst` looked like a lemon-shaped projectile icon.
This did not match the actual skill [[Behavior|Behavior]].
## 2. Skill Meaning
`Nova Burst` is not a missile, crystal shard, or thrown projectile.
Actual gameplay behavior:
- automatic radial AoE shockwave
- triggers around the player
- damages enemies inside the radius
- knocks enemies outward
- cooldown-based burst every few seconds
- evolves into `Nova Guardian`, which adds stronger golden guardian behavior
## 3. Art Direction Correction
The icon should communicate:
- central arcane core
- circular shockwave expansion
- radial force
- rune-like magitech energy
- area control around the player
It should not communicate:
- lemon
- fruit
- single projectile
- gem pickup
- missile tip
## 4. Fixes Applied
The procedural generator now creates `Nova Burst.png` with a dedicated `nova` icon shape.
New visual structure:
- cyan circular shockwave rings
- central navy magitech core
- arcane core light
- radial spokes showing outward force
- subtle purple secondary energy ring
The in-game Nova Burst renderer was also adjusted:
- center sprite is smaller and treated as a rune core
- expanding shockwave ring is now the main visual read
- added translucent pressure disk
- added segmented rune ring
- kept Guardian variant as gold/orange
## 5. Changed Runtime Paths
Important changed paths:
- `/Volumes/Data/project/Antigravity/Skybound/[[Scripts|Scripts]]/generate_magitech_assets.py`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/GameRenderer.ts`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/missiles/Nova Burst.png`
## 6. Verification
Asset generation completed successfully.
Production build completed successfully with:
```bash
npm run build
```
The existing `/sprites/player.png` static asset warning remains non-[[Blocking|Blocking]].
@@ -1,74 +0,0 @@
# Skybound Particle and Supply Readability Fix
**Date**: 2026-04-24
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Raw follow-up fix from gameplay screenshot review
## 1. Screenshot Issues
The reviewed screenshot exposed two readability problems.
Observed issues:
- Mint/cyan square particles were scattered across the floor and looked like items even though they could not be collected.
- The supply crate asset looked good, but it was not clear whether it was a player pickup or an enemy projectile/debris object.
## 2. Cause
### Mint Floor Squares
The mint squares were runtime particles from `EffectSystem`.
They were rendered in `GameRenderer.renderEffects()` using `fillRect()`, so every spark appeared as a small collectible-looking square.
These particles can come from combat hits, skill effects, EMP interactions, exp pickup feedback, or other short-lived feedbackSystems.
### Supply Ambiguity
The supply crate sprite itself was readable as an object, but the gameplay [[Affordance|Affordance]] was weak.
It needed explicit pickup language:
- pickup color
- capture ring
- directional marker
- short label
## 3. Fixes Applied
### Particle Shape
Runtime particles now render as small rotated diamond sparks instead of square floor blocks.
This keeps the magical spark feedback while reducing item confusion.
Normal shard fragments were also changed from square blocks to triangular fragments.
### Supply Pickup Readability
Supply drops now render with:
- mint-green dashed pickup ring
- soft pickup fill
- bobbing downward arrow
- retained supply crate sprite
- `PICK UP` label
This separates supply drops from enemy bullets, hazards, and cosmetic particles.
## 4. Changed Runtime Paths
Important changed path:
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/GameRenderer.ts`
## 5. Verification
Production build completed successfully with:
```bash
npm run build
```
The existing `/sprites/player.png` static path warning remains non-[[Blocking|Blocking]].
@@ -1,141 +0,0 @@
# Skybound Semirealistic Magitech Fantasy Redirection
**Date**: 2026-04-24
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Raw art direction correction before second asset pass
## 1. Reason for Redirection
The first generated art pack leaned too far into childish cartoon readability: thick outlines, flat toy-like shapes, and simplified symbolic silhouettes.
The new target is **Semirealistic Magitech Fantasy** for a top-down horde survival-shmup inspired by Survivor.io, aimed at players aged 12-18 and casual adults.
## 2. Core Concept
The visual library should feel detailed, grounded, and cool rather than cute.
Primary [[Reference|Reference]]s by feel:
- League of Legends-like readable fantasy detail
- Warhammer-like dark material weight
- Survivor.io-like top-down clarity and grid readability
This is still a game with high enemy density, so readability remains critical, but contrast should come from lighting, value, and energy color rather than thick black outlines.
## 3. Tone and Manner
### Semirealistic Magitech
Visual language:
- dark iron
- aged brass
- brushed [[Metal|Metal]]
- weathered stone
- glowing crystals
- engraved runes
- arcane circuitry
- controlled deep shadows
- focused magical highlights
Avoid:
- childish cartoon shapes
- toy-like flat icons
- heavy black outlines
- overly bright candy palettes
- large simplified emblem-only designs
## 4. Palette
Base colors:
- dark sapphire
- dark iron
- forest green
- weathered brass
- basalt gray
- deep crimson
Magic accents:
- arcane blue for player energy
- neon purple for corruption
- plasma red for enemy/boss danger
- molten orange for forge/lava accents
## 5. Asset Rules
### Player Vehicle
The player vehicle should read as a Magitech airship rather than a simple airplane.
Required traits:
- complex symmetrical or slightly asymmetrical hull
- dark iron and brass material mix
- intense crystalline power core
- smaller gun turrets
- visible engine components, gears, vents, and rune plates
- subtle energy glow readable from top-down view
### Enemies
Enemies should be threatening corrupted creatures or ancient mechanical horrors.
Examples:
- clockwork spiders with poison sacks
- rune golems made of dark stone
- corrupted winged drakes
- ancient mechanical horrors with plasma-red cores
### Background
Background should preserve Survivor.io-style grid readability but feel like an immersive fantasy environment.
Target environments:
- ancient overgrown Magitech city ruin
- subterranean magma forge
Rules:
- weathered stone pavement
- broken magitech circuitry embedded in the floor
- basalt structures
- subtle lava or arcane channels
- background contrast lower than enemies and player
### Effects
Player effects should be arcane blue or crystal cyan.
Enemy effects should lean plasma red, purple, or corrupted crimson.
Death effects should be optimized and satisfying:
- scrap metal shards
- dark crystal fragments
- arcane dust
- controlled flashes, not full-screen clutter
### UI
UI should use Survivor.io-like directness with a refined dark iron and crystal shell.
Required traits:
- heavy dark iron frames
- crystal level bar
- rune and gear details
- minimal but detailed HUD
- clean modern gothic / steampunk-inspired readability
## 6. Implementation Notes
The next pass should replace the first cartoony art pack with a darker semirealistic procedural raster set while preserving runtime file paths.
The existing generator should be rewritten so future [[Iteration|Iteration]]s can adjust palette, materials, and silhouettes consistently.
@@ -1,153 +0,0 @@
# Skybound Semirealistic Magitech Fantasy Art Pack
**Date**: 2026-04-24
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Superseded by semirealistic second pass
## 1. Direction
Skybound's 2D visual identity was first redirected toward **Stylized Casual Magitech**, then corrected into **Semirealistic Magitech Fantasy** after visual review.
The corrected target tone is a top-down survival shooter inspired by clear mobile action readability, but with more mature fantasy material treatment:
- reduced outlines
- dark iron and brass material language
- controlled lighting
- glowing crystalline cores
- corrupted magical enemies
- ancient magitech ruin backgrounds
- high contrast at small gameplay sizes
- color-coded enemy and weapon readability
- playful magitech forms instead of realistic military [[Hardware|Hardware]]
## 2. Core Art Rules
### Silhouette
Every gameplay object must remain readable at 36-72px on canvas.
- Player vehicles use triangular forward-facing silhouettes.
- Normal enemies use compact diamond/bug-like silhouettes.
- Elite enemies use wider, more decorated silhouettes.
- Bosses use tall central hulls with visible side modules and glowing cores.
- Weapons and drops use symbolic icons instead of detailed illustrations.
### Linework
Use value contrast and glow separation instead of heavy cartoon outlines.
[[Purpose|Purpose]]:
- separates sprites from busy scrolling backgrounds through lighting
- keeps bullets, drops, and enemies visible during VFX-heavy combat
- [[Support|Support]]s a grounded semirealistic style
### Lighting
Lighting is controlled and directional. Avoid noisy photorealism, but use subtle brushed [[Metal|Metal]], stone, and crystal texture.
Allowed:
- small inner highlights
- soft magical glow behind important objects
- subtle bevels
- material grain
- controlled shadow
Avoid:
- toy-like flat panels
- low-contrast smoke
- tiny greeble details
### Palette
Corrected palette:
- Void: `#080a12`
- Dark iron: `#1c2029`
- Aged brass: `#a57a37`
- Dark sapphire: `#102a52`
- Forest green: `#164535`
- Crimson: `#671a20`
- Arcane blue: `#36cdff`
- Neon purple: `#b03eff`
- Plasma red: `#ff4149`
- Molten orange: `#ff7a21`
## 3. Generated Asset Coverage
The following runtime assets were regenerated in-place under `public/sprites`:
- player airframes: `Falcon.png`, `rayce.png`
- charge shot: `chargeshot.png`
- normal enemies: `normal_enemy/enemy01.png` through `enemy09.png`
- elite enemies: `elite_enemy/elite01.png` through `elite16.png`
- bosses: `boss/tile000.png` through `tile010.png`
- turret atlas: `turret/turret_sprites.png`
- item drops: `item_drops_sprite.png`
- stage backgrounds: `background/stage_tile_1.png` through `stage_tile_8.png`
- weapon and skill icons under `sprites/missiles`
- core bullet, shield, currency, VFX sprites
- comms portraits: `portraits/hq_commander.png`, `portraits/pilot_standard.png`
## 4. UI Skin Coverage
The UI skin was added through:
- `src/features/game/styles/magitechArt.css`
- imported from `src/App.css`
The skin aligns:
- HUD panels
- level-up cards
- comms overlay
- hangar/action buttons
- warning text
- canvas saturation/contrast
## 5. Generator
The art pack is reproducible through:
`[[Scripts|Scripts]]/generate_magitech_assets.py`
This script uses the bundled Python runtime with Pillow and generates vector-like raster PNGs. It intentionally avoids relying on one-off manual image files so future palette or silhouette changes can be regenerated consistently.
## 6. Preview Sheet
Generated preview sheet:
`public/sprites/magitech_art_contact_sheet.png`
The preview sheet is for art review only and is not currently consumed by the game runtime.
## 7. Follow-up Art Tasks
Recommended next art pass:
1. Add animation frame variants for normal and elite enemies.
2. Split skill icons into a formal UI icon atlas instead of relying on individual PNGs.
3. Add boss-specific silhouettes matching the narrative names in `bossRegistry.ts`.
4. Add projectile color language documentation for player, enemy, boss, and gimmick bullets.
5. Replace remaining CSS vocabulary from older cyber-neon UI with magitech naming over time.
## 8. Second Pass Correction
After user review, the first art pack was judged too childish/cartoon-like. The generator and UI skin were rewritten.
Second pass changes:
- removed thick outlines
- added brushed metal / stone [[Noise|Noise]]
- added stronger shadows and glow-based separation
- changed vehicles into darker magitech airships
- changed enemies into corrupted mechanical/stone silhouettes
- changed backgrounds into darker stone grid ruins with broken circuitry
- changed UI from bright toy-card framing to dark iron/crystal framing
The reproducible generator remains:
`scripts/generate_magitech_assets.py`
@@ -1,102 +0,0 @@
# Skybound Stylized Casual Magitech Ingame Asset Fix
**Date**: 2026-04-24
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Raw follow-up fix from gameplay screenshot review
## 1. Screenshot Issues
The reviewed screenshots exposed three in-game visual problems.
Observed issues:
- `SUPPLY` air drop was rendered as a simple cyan ring and text label instead of a proper magitech supply crate.
- Enemy sprites showed a faint rectangular transparency box around the aircraft body.
- Large falling translucent circular hazards were rendered as plain gray circles and did not match the Stylized Casual Magitech tone.
## 2. Cause
### Supply Drop
The supply drop was not using an image asset.
It was drawn directly in `GameRenderer.renderAirDrops()` as:
- animated circle stroke
- translucent cyan fill
- white `SUPPLY` text
### Enemy Rect[[ANGLE|ANGLE]] Artifact
The procedural generator used glow layers and Lanczos downsampling.
This left very low alpha pixels across the image canvas. In gameplay, those tiny alpha values became visible as a faint rectangular box around enemies.
### Falling Circular Hazard
The falling translucent circle was an `EMP_CLOUD` hazard.
It was drawn directly in `GameRenderer.renderHazards()` as a generic gray filled circle.
## 3. Fixes Applied
### Supply Drop Asset
A new stylized magitech crate sprite was generated:
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/supply_crate.png`
The renderer now draws this crate for air drops while preserving a small dashed cyan capture ring.
### Alpha Cleanup
The procedural asset generator now clamps very low alpha values to `0` during PNG export.
This removes transparent rectangle artifacts while keeping intended outlines, glow, and silhouettes.
Verified enemy sprite alpha:
- normal enemy corner alpha: `0`
- elite enemy corner alpha: `0`
- boss corner alpha: `0`
- no alpha values below the cleanup threshold remain
### Hazard Assets
New hazard sprites were generated:
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/vfx/vfx_hazard_emp.png`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/vfx/vfx_hazard_asteroid.png`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/vfx/vfx_hazard_debris.png`
`EMP_CLOUD` now renders as an arcane rune-field instead of a plain gray circle.
`ASTEROID` and `DEBRIS` can render as stylized magitech rock fragments instead of fallback circles.
## 4. Changed Runtime Paths
Important changed or generated paths:
- `/Volumes/Data/project/Antigravity/Skybound/[[Scripts|Scripts]]/generate_magitech_assets.py`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/hooks/useGameAssets.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/GameRenderer.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/utils/SpriteUtils.ts`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/supply_crate.png`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/vfx/vfx_hazard_emp.png`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/vfx/vfx_hazard_asteroid.png`
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/vfx/vfx_hazard_debris.png`
## 5. Verification
Asset generation completed successfully.
Alpha inspection confirmed transparent corners and no low-alpha rectangle residue for the checked enemy/boss/supply/hazard sprites.
Production build completed successfully with:
```bash
npm run build
```
The build still [[Reports|Reports]] the existing `/sprites/player.png` static path warning, but it remains non-[[Blocking|Blocking]] and the production bundle was generated successfully.
@@ -1,177 +0,0 @@
# Skybound Survivor-Like Balance Curve Pass
**Date**: 2026-04-24
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Raw gameplay balance pass from user playtest feedback
## 1. Playtest Feedback
The game shell looked close to Survivor.io / Vampire Survivors, but the actual gameplay did not feel like that genre.
Reported issues:
- gameplay did not deliver enough horde-survival pressure
- stage balance felt uneven
- TAC Level Up pacing felt unbalanced
- growth did not form a satisfying user-facing curve
## 2. Diagnosis
The previous balance leaned closer to a shmup / tactical shooter.
Main causes found in code:
- simultaneous enemy cap was too low for a horde-survival feel
- procedural spawn did not fully use the timeline `spawnIntervalMult`
- early EXP requirement was too high
- EXP growth multiplier was too steep
- stage difficulty scaled enemy/bullet stats too aggressively
- stage scripted [[Events|Events]] were compressed too early in the timeline
- TAC Level Up card offers were weighted but not structured, so the user could receive awkward choices
- starter skill offers could omit key horde-survival archetypes
## 3. Target Curve
New target:
- first meaningful upgrade should arrive quickly
- player should see more enemies on screen
- enemies should be individually weaker
- danger should come from density and positioning, not bullet stat spikes
- level-up choices should consistently [[Support|Support]] build formation
- stage progression should rise smoothly rather than jump sharply
## 4. Applied Balance Changes
### EXP and Level-Up
Changes:
- initial required EXP lowered from `100` to `45`
- normal enemy EXP increased from `5` to `7`
- elite EXP increased from `25` to `32`
- level-up EXP multiplier changed from steep `1.60 / 1.72 / 1.85` to smoother `1.24 / 1.30 / 1.36 / 1.42`
Expected result:
- early TAC Level Ups arrive faster
- the player can form a build before the first spike
- later progression still slows down without becoming a wall
### TAC Level Up Card Structure
The card generator now tries to offer:
- one owned skill upgrade
- one [[Synergy|Synergy]] / spike-counter / EVO-supporting option
- one flexible option
Expected result:
- fewer dead-choice screens
- higher chance of completing coherent builds
- less frustration from random-only card pools
### Starter Selection
Starter cards now come from three archetype buckets:
- primary damage
- area / crowd control
- utility / defense
Expected result:
- every run begins with a usable horde-survival foundation
- the first choice feels strategic without becoming punishing
### Enemy Density and Spawning
Changes:
- hard enemy cap increased from `30` to `90`
- timeline phase caps increased by stage and phase
- procedural spawn interval now uses `spawnIntervalMult`
- procedural spawns can arrive in small batches
- formation spawns now occur more often
- individual enemy HP and speed were reduced to support higher density
- elite chance is now a gradual probability instead of flipping too hard by difficulty
Expected result:
- more screen-filling horde pressure
- less empty movement time
- more satisfying weapon-clearing moments
### Stage Curve
Changes:
- stage duration curve changed from `120 + stage * 30s` to `150 + stage * 18s`
- stage difficulty scaling reduced from steep `+0.4 per stage` to smoother `+0.18 per stage`
- phase difficulty multipliers were lowered
- phase enemy caps were increased
- scripted wave events are distributed across the stage instead of firing too early
Expected result:
- stages feel less spiky and more readable
- difficulty rises through density and phase rhythm
- player has time to grow before major pressure events
### Enemy Bullet and Damage Pressure
Changes:
- enemy bullet speed curves were reduced
- damage curves were reduced
- bullet caps were reduced
- global enemy bullet speed multiplier reduced
- enemy projectile damage multipliers reduced
Expected result:
- gameplay moves away from bullet-hell punishment
- movement pressure still exists, but horde positioning becomes the main focus
### Weapon Rhythm
Several weapon cooldowns were shortened so early picks feel active sooner.
Nova Burst was also adjusted to trigger sooner and scale more clearly as an AoE crowd-control tool.
## 5. Changed Runtime Paths
Important changed paths:
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/balance.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/CombatTimeline.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/weapon[[Behavior|Behavior]]s.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/SpawnerSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ModularWeaponSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/hooks/useGameEngine.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/store/useGameStore.ts`
## 6. Verification
Production build completed successfully with:
```bash
npm run build
```
The existing `/sprites/player.png` static path warning remains non-[[Blocking|Blocking]].
## 7. Next Playtest Questions
Recommended next playtest checks:
- Does the first level-up happen within a satisfying time window?
- Does the screen feel populated without becoming unreadable?
- Do weapons feel like they clear hordes?
- Do stage spikes feel earned rather than sudden?
- Does TAC Level Up usually offer at least one desirable choice?
@@ -1,60 +0,0 @@
# Datacollector - 인증 복구 후 자동 재개 상태 전환 수정
- 작성 시각: 2026-04-25 22:39:30 KST
- 프로젝트: `/Volumes/Data/project/Antigravity/Datacollector`
- 관련 파일: `src/components/AgentDashboard.tsx`, `src/lib/engine.ts`
## 상황
NotebookLM 인증 복구 로직을 강화했지만, 화면에서는 여전히 `CONTINUE MISSION` 버튼을 사용자가 눌러야 다음 큐가 이어지는 것처럼 보였다.
사용자 관찰:
- 작업은 일부 완료됨.
- 큐에는 아직 작업이 많이 남아 있음.
- 헤더 상태가 `IDLE`로 보임.
- `CONTINUE MISSION` 버튼이 사용자의 수동 클릭을 기다림.
## 원인
프론트엔드 상태 전환에 빈틈이 있었다.
`AgentDashboard``useEffect``status !== 'running'`일 때 `KnowledgeEngine.stop()`을 호출한다. 그런데 기존 `stop()`은 내부 실행 플래그만 끄는 것이 아니라 항상 Zustand 상태까지 `idle`로 바꿨다.
그 결과 인증 오류 등으로 `paused` 상태를 유지해야 하는 경우에도 React effect를 지나면서 `paused -> idle`로 바뀌었다. 이렇게 되면 앱은 "복구 후 자동 재개 가능한 일시정지"가 아니라 "사용자가 다시 Continue를 눌러야 하는 대기 상태"처럼 동작했다.
## 조치
`src/lib/engine.ts`:
- `stop(updateStatus = true)` 형태로 변경했다.
- 내부 엔진만 멈춰야 할 때는 UI 상태를 덮어쓰지 않도록 했다.
`src/components/AgentDashboard.tsx`:
- `status !== 'running'` effect에서는 `engine.stop(false)`를 호출하도록 변경했다.
- `status === 'paused'`이고 큐가 남아 있으면 NotebookLM 연결 확인 후 자동으로 `running`으로 되돌리는 auto-resume effect를 추가했다.
- 기존 버그로 이미 `idle`에 갇힌 화면도 구제하기 위해, 수동 정지나 작업 완료 로그가 없는 `idle + 남은 큐` 상태도 복구 가능한 멈춤으로 보고 자동 재개하도록 보강했다.
- 중복 자동 재개를 막기 위해 `autoResumeRef` 잠금을 추가했다.
## 검증
다음 검증을 완료했다.
```bash
npm run lint
curl -sS -I http://127.0.0.1:3000
curl -sS -X POST http://127.0.0.1:3002/api/check-connection
```
결과:
- TypeScript 검사 통과
- 프론트엔드 서버 응답 정상
- NotebookLM 브리지 연결 확인 `success: true`
## 운영 메모
앞으로 인증 복구나 연결 복구로 인해 `paused` 상태가 되면 앱이 NotebookLM 연결을 확인하고 자동으로 다음 큐를 이어서 실행한다.
사용자가 직접 `STOP / PAUSE`를 누른 경우는 기존처럼 `idle`로 유지되므로, 수동 정지는 자동 재개 대상이 아니다.
@@ -1,72 +0,0 @@
# Datacollector Bridge Connection Refused Run Script Fix
Date: 2026-04-25 21:07:52 KST
Project: Datacollector
[[Repository|Repository]]: `/Volumes/Data/project/Antigravity/Datacollector`
## Summary
사용자가 앱 실행 후 `POST http://127.0.0.1:3002/api/check-connection net::ERR_CONNECTION_REFUSED` 오류를 확인했다.
이는 NotebookLM 인증 실패가 아니라 MCP Bridge 서버가 실행되지 않아 브라우저가 `3002` 포트에 연결하지 못한 상태였다.
## Root Cause
실행 경로가 여러 개였고 일부 경로는 프런트엔드 Vite 서버만 실행했다.
- `run_mac.command`: Bridge와 Vite를 함께 실행
- `run_app.sh`: Vite만 실행
- `npm run dev`: Vite만 실행
따라서 `run_app.sh` 또는 `npm run dev`로 앱을 켜면 UI는 열리지만 `/api/check-connection` 요청을 받을 Bridge 서버가 없어 `ERR_CONNECTION_REFUSED`가 발생했다.
## Changes Made
수정 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/run_app.sh`
- `/Volumes/Data/project/Antigravity/Datacollector/README.md`
- `/Volumes/Data/project/Antigravity/Datacollector/src/lib/api.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/src/components/AgentDashboard.tsx`
- `/Volumes/Data/project/Antigravity/Datacollector/src/lib/engine.ts`
핵심 변경:
- `run_app.sh`가 Bridge 서버와 Vite 서버를 함께 실행하도록 변경
- `run_app.sh` 시작 시 기존 `3000`, `3002` 포트 프로세스를 정리
- 종료 시 Bridge 백그라운드 프로세스도 함께 종료하도록 trap 추가
- README의 실행 안내를 `npm run dev` 단독에서 `./run_mac.command` 또는 `npm run start-full`로 변경
- `src/lib/api.ts``bridgeFetch()` 추가
- Bridge 연결 실패 시 `Failed to fetch` 대신 “Bridge 서버가 실행되지 않았다”는 안내 메시지를 표시하도록 변경
- `VITE_BRIDGE_URL`로 Bridge 주소를 override할 수 있게 함
## Verification
실행한 검증:
```bash
node --check [[Scripts|Scripts]]/mcp_bridge.mjs
npm run lint
npm run build
```
검증 결과:
- 브리지 문법 체크 통과
- TypeScript 타입체크 통과
- Vite 프로덕션 빌드 통과
## [[Opera|Opera]]tional Note
앞으로 앱은 아래 방식으로 실행해야 한다.
```bash
./run_mac.command
```
또는 수동으로 두 서버를 같이 실행한다.
```bash
npm run start-full
```
`npm run dev`만 실행하면 프런트엔드만 뜨므로 NotebookLM, Wiki save, 인증 복구 API가 동작하지 않는다.
@@ -1,177 +0,0 @@
# Datacollector Codebase Structure Review and Initial Risk [[Assessment|Assessment]]
Date: 2026-04-25 20:38:01 KST
Project: Datacollector
[[Repository|Repository]]: `/Volumes/Data/project/Antigravity/Datacollector`
Knowledge Vault: `/Volumes/Data/project/Antigravity/Wiki/00_Raw`
## Summary
이 문서는 Datacollector 프로젝트의 첫 구조 파악 및 초기 코드 리뷰 결과를 정리한 기록이다.
이번 검토의 목적은 이후 기능 개발 전에 현재 시스템의 책임 분리, 실행 흐름, 외부 의존성, 그리고 우선적으로 손봐야 할 위험 요소를 이해하는 데 있다.
현재 프로젝트는 단순한 프런트엔드 앱이 아니라, React 기반 UI와 Zustand 상태 저장소, 자율 실행 엔진, 그리고 NotebookLM MCP 및 로컬 LM을 연결하는 Express 브리지 서버가 결합된 자동화 연구 도구 형태로 구성되어 있다.
## High-Level [[Architecture|Architecture]]
전체 흐름은 아래와 같다.
`React UI -> Zustand Store -> KnowledgeEngine -> Express Bridge -> NotebookLM MCP / Local LM / GitHub / Wiki [[Storage|Storage]]`
핵심 책임 분리는 다음과 같이 이해했다.
- `src/components/AgentDashboard.tsx`
사용자 인터페이스, 미션 시작/중지/재개, 설정 입력, 로그 표시, 수동 커밋 등 상호작용 담당
- `src/store/agentStore.ts`
앱 전체 설정값과 실행 상태를 보관하는 단일 전역 상태 저장소
- `src/lib/engine.ts`
큐를 소비하며 연구, 합성, 링크 추출, 다음 토픽 확장을 반복하는 자율 엔진
- `src/lib/gemini.ts`
NotebookLM 미연결 시 사용하는 로컬 LM 프롬프트 생성 및 응답 파싱
- `src/lib/github.ts`
결과 Markdown을 GitHub 저장소의 `00_Raw/` 경로로 업로드
- `[[Scripts|Scripts]]/mcp_bridge.mjs`
NotebookLM MCP 서버와 통신하는 지속 프로세스형 브리지 서버
## Execution Flow
실행 흐름은 다음 순서로 이해했다.
1. 사용자가 `AgentDashboard`에서 주제를 입력하고 미션을 시작한다.
2. 주제와 설정이 `agentStore`에 기록되고 상태가 `running`으로 바뀐다.
3. `status` 변경을 감지한 UI가 `KnowledgeEngine` 싱글톤을 시작한다.
4. `KnowledgeEngine`는 큐의 첫 항목을 읽고 현재 깊이와 루트 주제를 기준으로 처리 여부를 결정한다.
5. NotebookLM 연결 상태가 좋으면 브리지 서버를 통해 리서치와 합성을 수행한다.
6. NotebookLM이 없으면 로컬 LM 프록시(`/api/lm`)를 통해 대체 연구를 진행한다.
7. 생성된 Markdown에서 위키 링크를 추출해 다음 큐를 구성한다.
8. 결과는 pending commits, completed 목록, 로컬 위키 Raw 저장소 등에 반영된다.
## Current Structure Notes
이번 시점에서 구조적으로 눈에 띈 특징은 다음과 같다.
- 상태 관리가 거의 전부 Zustand store 하나에 집중되어 있어 흐름 추적은 쉽다.
- 대신 엔진과 UI가 store를 매우 직접적으로 공유해서 결합도가 높다.
- NotebookLM 경로와 Local LM 경로가 모두 존재해 fallback 전략은 분명하다.
- 브리지 서버가 프런트엔드 백엔드이자 외부 도구 래퍼 역할까지 함께 맡고 있어 책임이 넓다.
- 문서 저장 흐름이 GitHub 업로드와 로컬 위키 저장으로 이중화되어 있다.
## Review Findings
### 1. Sensitive secrets are persisted in [[Browser|Browser]] storage
`githubToken``notebookLmCookies`가 Zustand persist 설정에 포함되어 있어 브라우저 localStorage에 평문으로 저장된다.
이 방식은 세션 쿠키나 GitHub 토큰 같은 민감 정보의 저장 위치로는 안전하지 않다.
관련 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/src/store/agentStore.ts`
영향:
- 같은 브라우저 프로필을 사용하는 다른 코드나 도구가 정보에 접근할 수 있다.
- 장기적으로 토큰 유출 위험이 커진다.
### 2. Bridge server is exposed too broadly
브리지 서버는 `0.0.0.0:3002`로 열리고 CORS도 전부 허용한다.
또한 `/api/lm`은 클라이언트가 전달한 임의의 URL로 요청을 프록시할 수 있다.
관련 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/scripts/mcp_bridge.mjs`
영향:
- 로컬 개발용으로는 편하지만, 같은 네트워크 안에서 예상하지 않은 접근 통로가 될 수 있다.
- 사실상 무인증 프록시처럼 동작할 여지가 있다.
### 3. Environment portability is weak
MCP 실행 파일 경로와 위키 저장 경로가 절대경로로 하드코딩되어 있다.
관련 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/scripts/mcp_bridge.mjs`
영향:
- 다른 개발자 머신, 다른 사용자 계정, 다른 운영체제에서 그대로 실행하기 어렵다.
- 배포보다는 특정 개인 작업 환경에 강하게 종속된다.
### 4. Manual handoff [[State|State]] is not fully cleared
`resolveManualNext`가 store에 함수 형태로 저장되는데, `clearState()`에서 정리되지 않는다.
수동 합성 대기 중 reset 또는 새 미션 시작이 발생하면 상태 꼬임 가능성이 있다.
관련 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/src/store/agentStore.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/src/lib/engine.ts`
영향:
- 이전 미션의 대기 상태가 다음 미션에 잔존할 수 있다.
- UI 버튼 상태와 실제 엔진 대기 상태가 어긋날 수 있다.
### 5. API endpoint usage is duplicated and hardcoded
프런트엔드에는 이미 Vite 프록시가 설정되어 있지만, UI와 엔진 코드 곳곳에서 `http://127.0.0.1:3002`를 직접 호출하고 있다.
관련 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/src/components/AgentDashboard.tsx`
- `/Volumes/Data/project/Antigravity/Datacollector/src/lib/engine.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/vite.config.ts`
영향:
- 포트 변경이나 배포 환경 변경 시 수정 지점이 늘어난다.
- 런타임 경로 설정이 한 군데에서 관리되지 않는다.
## Validation Performed
이번 검토 중 아래 확인을 수행했다.
- 저장소 파일 구조 및 진입점 확인
- UI, store, engine, bridge, GitHub, Local LM 계층 코드 확인
- `npm run lint` 실행
검증 결과:
- TypeScript 타입체크는 현재 통과했다.
## Suggested Next Priorities
우선순위는 아래 순서가 적절하다.
1. 민감 정보 저장 방식을 localStorage 바깥으로 이동하거나 최소한 분리
2. 브리지 서버 바인딩 범위와 CORS 정책 축소
3. 절대경로를 환경변수 또는 설정 파일로 치환
4. `resolveManualNext`를 포함한 미션 종료 정리 로직 강화
5. API 베이스 URL을 단일 설정 지점으로 통합
## Working Agreement For Future Notes
사용자 요청에 따라, 앞으로 Datacollector 관련 조사/분석/리뷰 결과는 가능하면 이 지식 창고 경로에 계속 기록한다.
기본 원칙:
- 위치: `/Volumes/Data/project/Antigravity/Wiki/00_Raw`
- 파일명: `YYYY-MM-DD-<Project>_<Topic>.md` 또는 기존 저장소 관례와 유사한 읽기 쉬운 영어 제목
- 내용: 작업 목적, 파악한 구조, 핵심 발견사항, 다음 액션을 포함
## Source Files Reviewed
- `/Volumes/Data/project/Antigravity/Datacollector/README.md`
- `/Volumes/Data/project/Antigravity/Datacollector/package.json`
- `/Volumes/Data/project/Antigravity/Datacollector/vite.config.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/src/main.tsx`
- `/Volumes/Data/project/Antigravity/Datacollector/src/App.tsx`
- `/Volumes/Data/project/Antigravity/Datacollector/src/components/AgentDashboard.tsx`
- `/Volumes/Data/project/Antigravity/Datacollector/src/store/agentStore.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/src/lib/engine.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/src/lib/gemini.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/src/lib/github.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/scripts/mcp_bridge.mjs`
- `/Volumes/Data/project/Antigravity/Datacollector/scripts/mcp_caller.py`
@@ -1,74 +0,0 @@
# Datacollector Local Wiki Save Only Output Mode
Date: 2026-04-25 20:50:41 KST
Project: Datacollector
[[Repository|Repository]]: `/Volumes/Data/project/Antigravity/Datacollector`
## Summary
Datacollector의 생성 결과 저장 방식을 GitHub 업로드 중심에서 로컬 Wiki 저장 전용으로 정리했다.
앞으로 앱에서 생성되는 연구 문서는 `/Volumes/Data/project/Antigravity/Wiki/00_Raw`에 저장되고, Git 업로드는 사용자가 나중에 별도로 한 번에 처리하는 운영 방식으로 둔다.
## Previous [[Behavior|Behavior]]
기존 흐름은 결과 생성 후 두 경로가 동시에 존재했다.
- 로컬 Wiki Raw 폴더에 자동 저장
- `pendingCommits`에 결과를 쌓고 UI의 `BATCH COMMIT` 버튼으로 GitHub 업로드 가능
이 방식은 앱 안에 GitHub 토큰과 저장소 설정을 유지해야 했고, 사용자가 의도하지 않아도 Git 업로드 기능이 계속 노출되는 구조였다.
## New Behavior
새 흐름은 다음과 같다.
1. 연구 결과 Markdown 생성
2. `saved[[Reports|Reports]]`에 프리뷰용 로컬 캐시 저장
3. 브리지 서버의 `/api/wiki/save`를 통해 `/Volumes/Data/project/Antigravity/Wiki/00_Raw`에 Markdown 파일 저장
4. GitHub 업로드 버튼이나 토큰 설정 없이 완료
GitHub 업로드는 앱이 수행하지 않는다.
## Changes Made
수정 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/src/store/agentStore.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/src/lib/engine.ts`
- `/Volumes/Data/project/Antigravity/Datacollector/src/components/AgentDashboard.tsx`
- `/Volumes/Data/project/Antigravity/Datacollector/.env.example`
삭제 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/src/lib/github.ts`
핵심 변경:
- `githubToken`, `githubRepoUrl` 상태 제거
- `pendingCommits` 제거
- `addPendingCommit`, `clearPendingCommits` 제거
- `savedReports``addSavedReport` 추가
- `BATCH COMMIT` 버튼 제거
- 설정 모달의 GitHub Wiki Sync 섹션 제거
- `.env.example`의 GitHub 설정 제거
- 생성 결과는 기존 Wiki 저장 API를 통해 로컬 Raw 폴더에만 저장
## Verification
실행한 검증:
```bash
npm run lint
npm run build
```
검증 결과:
- TypeScript 타입체크 통과
- Vite 프로덕션 빌드 통과
## Notes
로컬 Wiki 저장은 기존 브리지 서버의 `/api/wiki/save` 라우트를 그대로 사용한다.
저장 대상 경로는 현재 브리지 서버에 하드코딩된 `/Volumes/Data/project/Antigravity/Wiki/00_Raw`이다.
추후 이 경로도 `.env` 설정으로 분리하면 다른 머신이나 폴더 구조에서도 더 쉽게 운영할 수 있다.
@@ -1,50 +0,0 @@
# Datacollector Mac Windows Launcher [[Scripts|Scripts]]
Date: 2026-04-25 21:09:42 KST
Project: Datacollector
[[Repository|Repository]]: `/Volumes/Data/project/Antigravity/Datacollector`
## Summary
Datacollector 실행 시 Vite 프런트엔드만 뜨고 MCP Bridge 서버가 뜨지 않아 `ERR_CONNECTION_REFUSED`가 발생할 수 있었다.
이를 막기 위해 맥용과 윈도우용 실행 파일을 명확히 정리했다.
## Main Launchers
- macOS: `/Volumes/Data/project/Antigravity/Datacollector/run_mac.command`
- Windows: `/Volumes/Data/project/Antigravity/Datacollector/run_win.bat`
두 실행 파일 모두 아래를 수행한다.
1. 프로젝트 폴더로 이동
2. `node_modules`가 없으면 `npm install`
3. 기존 `3000`, `3002` 포트 프로세스 정리
4. MCP Bridge 서버 실행
5. Vite 앱 실행
## Compatibility Wrappers
기존 실행 파일과의 호환성을 위해 아래 파일은 메인 실행 파일로 위임하도록 단순화했다.
- `run_app.sh` -> `run_mac.command`
- `run_app.bat` -> `run_win.bat`
## Verification
실행한 검증:
```bash
bash -n run_mac.command
bash -n run_app.sh
npm run lint
```
검증 결과:
- macOS shell script 문법 통과
- TypeScript 타입체크 통과
## [[Opera|Opera]]tional Note
앞으로 맥에서는 `run_mac.command`, 윈도우에서는 `run_win.bat`만 실행하면 된다.
`npm run dev` 단독 실행은 프런트엔드만 켜므로 NotebookLM, Wiki save, 인증 복구 API가 동작하지 않는다.
@@ -1,68 +0,0 @@
# Datacollector - NotebookLM 인증 브라우저 유지 및 오래된 .env 쿠키 우선순위 문제 해결
- 작성 시각: 2026-04-25 21:31:00 KST
- 프로젝트: `/Volumes/Data/project/Antigravity/Datacollector`
- 관련 파일: `[[Scripts|Scripts]]/mcp_bridge.mjs`, `auth_mac.command`, `auth_win.bat`, `.env.example`
## 상황
앱에서 `/api/check-connection` 호출이 500으로 실패했고, 화면에는 다음과 같은 메시지가 반복되었다.
- `Authentication expired`
- `인증 자동 복구 실패. 브라우저 로그인이 필요한 상태일 수 있습니다.`
- `MCP initialized: true, pending: 0`
사용자는 NotebookLM 인증 중 [[Chrome|Chrome]]이 열렸다가 닫히는 점을 보고, 인증 브라우저를 유지해야 하는 것 아니냐고 질문했다.
## 확인한 내용
`notebooklm-mcp-auth` 소스 확인 결과, 기본 자동 실행 모드는 인증 후 자신이 띄운 Chrome 프로세스를 종료한다. 반면 `--no-auto-launch --port ... --user-data-dir ...` 모드는 이미 떠 있는 Chrome 디버깅 세션에 붙기 때문에 인증 브라우저를 유지할 수 있다.
브리지에서 Chrome을 유지하도록 바꾼 뒤 인증 CLI는 성공했다. 하지만 MCP 서버의 `notebook_list`는 여전히 `Authentication expired`를 반환했다.
추가 확인 결과, `.env`에 예전 `NOTEBOOKLM_COOKIES` 값이 남아 있었다. `scripts/mcp_bridge.mjs``dotenv/config`를 로드한 뒤 MCP 서버를 자식 프로세스로 실행하면서 이 오래된 환경변수 쿠키가 `~/.notebooklm-mcp/auth.json`의 최신 인증 캐시보다 우선 적용되고 있었다.
즉 실제 핵심 원인은 다음 조합이었다.
- 인증 CLI는 최신 쿠키를 `~/.notebooklm-mcp/auth.json`에 정상 저장함.
- 브리지는 `.env`의 오래된 `NOTEBOOKLM_COOKIES`를 MCP 자식 프로세스에 전달함.
- MCP 서버는 캐시 파일보다 환경변수를 우선 사용함.
- 결과적으로 새 인증 후에도 MCP는 계속 오래된 쿠키로 NotebookLM API를 호출함.
## 조치
`scripts/mcp_bridge.mjs`에서 기본적으로 MCP 자식 프로세스와 인증 CLI 자식 프로세스에 `NOTEBOOKLM_COOKIES`, `NOTEBOOKLM_CSRF_TOKEN`, `NOTEBOOKLM_SESSION_ID`를 넘기지 않도록 수정했다.
명시적으로 환경변수 인증을 사용해야 할 경우에는 `.env`에 아래 값을 둔다.
```env
USE_NOTEBOOKLM_ENV_AUTH="true"
```
기본값은 `false`이며, 이 경우 `notebooklm-mcp-auth`가 생성한 `~/.notebooklm-mcp/auth.json` 캐시를 우선 사용한다.
또한 `auth_mac.command`, `auth_win.bat`는 별도 Chrome 프로필과 디버깅 포트를 사용해 NotebookLM 인증 브라우저를 열어두는 방식으로 변경했다.
## 검증
다음 검증을 완료했다.
```bash
node --check scripts/mcp_bridge.mjs
npm run lint
curl -sS -X POST http://127.0.0.1:3002/api/check-connection
```
결과:
```json
{"success":true,"count":0}
```
직접 Python MCP 클라이언트로도 같은 인증 캐시를 사용해 `list_notebooks` 호출이 성공했고, 노트북 89개를 읽는 것을 확인했다.
## 운영 메모
앞으로는 `.env`에 오래된 `NOTEBOOKLM_COOKIES`가 남아 있어도 기본 브리지 실행에는 영향을 주지 않는다. 다만 혼란을 줄이려면 장기적으로 `.env`에서 `NOTEBOOKLM_COOKIES` 줄을 삭제하거나 주석 처리하는 것이 좋다.
NotebookLM 인증용 Chrome 창은 닫지 않는 것이 좋다. 인증이 풀렸을 때 브리지가 같은 디버깅 포트의 Chrome 세션에 붙어 자동 복구를 시도할 수 있다.
@@ -1,85 +0,0 @@
# Datacollector NotebookLM Automatic Auth Recovery
Date: 2026-04-25 20:47:05 KST
Project: Datacollector
[[Repository|Repository]]: `/Volumes/Data/project/Antigravity/Datacollector`
## Summary
컴퓨터 포맷 이후 NotebookLM MCP 인증이 자주 실패하고, 20-30분마다 `auth_mac.command`를 수동 실행해야 하는 문제가 있었다.
이번 작업에서는 인증 만료 시 브리지 서버가 자동으로 복구를 시도하도록 개선했다.
## Root Cause Hypothesis
기존 구조는 MCP 서버의 `refresh_auth` 도구 호출에만 의존했다.
하지만 포맷 이후 로컬 토큰 저장 위치나 [[Chrome|Chrome]] 세션 상태가 달라지면서 `refresh_auth`만으로 복구되지 않는 상황이 발생할 수 있다.
사용자가 직접 실행하던 파일은 다음 명령의 래퍼였다.
```bash
/Users/g1nation_mac/.local/bin/notebooklm-mcp-auth
```
따라서 자동 복구 흐름에도 이 CLI 인증 명령을 포함시키는 것이 가장 직접적인 개선 방향이다.
## Changes Made
수정 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/[[Scripts|Scripts]]/mcp_bridge.mjs`
- `/Volumes/Data/project/Antigravity/Datacollector/src/components/AgentDashboard.tsx`
- `/Volumes/Data/project/Antigravity/Datacollector/.env.example`
핵심 변경:
- 브리지 서버가 `.env`를 읽도록 `dotenv/config`를 추가했다.
- `AUTH_PATH`, `AUTH_ARGS`, `AUTH_TIMEOUT_MS`, `AUTH_REFRESH_INTERVAL_MS` 설정을 추가했다.
- MCP 인증 에러 발생 시 `refresh_auth`를 먼저 시도한다.
- `refresh_auth` 실패 시 MCP 프로세스를 재시작하고 다시 갱신을 시도한다.
- 그래도 실패하면 `notebooklm-mcp-auth` CLI를 브리지 서버가 직접 실행한다.
- CLI 인증 후 MCP 프로세스를 재시작해 새 토큰을 읽게 만든다.
- 장시간 실행 중에는 15분 간격으로 요청이 없는 시점에 인증 상태를 사전 갱신한다.
- UI 안내 문구를 수동 재인증 중심에서 자동 복구 중심으로 수정했다.
## Runtime [[Behavior|Behavior]]
새 인증 복구 순서:
1. NotebookLM MCP 요청 실패
2. 에러 메시지가 인증 관련인지 판단
3. `refresh_auth` 호출
4. MCP 프로세스 재시작 후 `refresh_auth` 재시도
5. `notebooklm-mcp-auth` CLI 자동 실행
6. MCP 프로세스 재시작
7. 원래 실패했던 NotebookLM 요청 재시도
주기적 갱신:
- 기본 간격: 15분
- 설정값: `AUTH_REFRESH_INTERVAL_MS=900000`
- 진행 중인 MCP 요청이 있을 때는 건드리지 않고 건너뛴다.
## Verification
실행한 검증:
```bash
node --check scripts/mcp_bridge.mjs
npm run lint
npm run bridge
curl -s http://127.0.0.1:3002/api/health
```
검증 결과:
- `node --check` 통과
- TypeScript 타입체크 통과
- 브리지 서버 시작 성공
- MCP 서버 초기화 성공
- `/api/health`에서 `connected: true`, `version: 3.3.0`, `authPath` 확인
## Notes
완전히 백그라운드 인증이 가능한지는 Google/Chrome 세션 상태에 의존한다.
브라우저 로그인이 만료되어 실제 사용자 로그인이 필요한 상태라면 자동 CLI 실행도 브라우저 로그인을 요구할 수 있다.
다만 기존처럼 매번 사용자가 batch 파일을 직접 실행하는 흐름보다, 일반적인 토큰 만료와 MCP refresh 실패 상황은 브리지 서버가 먼저 복구하도록 개선되었다.
@@ -1,60 +0,0 @@
# Datacollector - NotebookLM 자동 재인증 검증 강화 및 동시 복구 잠금
- 작성 시각: 2026-04-25 22:17:33 KST
- 프로젝트: `/Volumes/Data/project/Antigravity/Datacollector`
- 관련 파일: `[[Scripts|Scripts]]/mcp_bridge.mjs`
## 상황
인증 브라우저 유지와 오래된 `.env` 쿠키 우선순위 문제를 해결한 뒤에도, 실제 작업 중 인증이 풀렸을 때 완전히 자동으로 재인증되지 않는 문제가 남아 있었다.
화면에서는 작업은 진행되지만 사용자가 기대한 "인증 만료 감지 -> 자동 재인증 -> 원래 작업 재시도" 흐름이 안정적으로 보장되지 않았다.
## 원인
브리지에는 자동 복구 로직이 있었지만 두 가지 빈틈이 있었다.
- `refresh_auth` 호출이 성공해도 실제 NotebookLM API 호출이 가능한지 검증하지 않았다.
- `/api/re-auth``/api/check-connection` 같은 요청이 동시에 들어오면 각각 MCP 재시작과 인증 복구를 시도해서 프로세스 재시작 경합이 생길 수 있었다.
추가로 인증 오류 판별 문자열에 `expired`, `RPC Error 16`, `csrf`, `만료` 같은 케이스가 충분히 포함되지 않아 일부 인증 만료 메시지가 일반 오류로 처리될 가능성이 있었다.
## 조치
`scripts/mcp_bridge.mjs`에서 다음을 수정했다.
- 재인증 성공 기준을 `refresh_auth` 성공이 아니라 실제 `notebook_list` 호출 성공으로 강화했다.
- 인증 만료 감지 시 `refreshAuth({ allowExternalAuth: true })`를 통해 자동 CLI 인증 복구까지 이어지도록 정리했다.
- 주기적 인증 점검도 필요 시 외부 인증 CLI 복구를 허용하도록 변경했다.
- `_refreshAuthPromise` 잠금을 추가해 동시 재인증/재시작 요청이 서로 충돌하지 않게 했다.
- 인증 오류 감지 키워드에 `expired`, `rpc error 16`, `csrf`, `unauthorized`, `forbidden`, `인증`, `만료`를 추가했다.
## 검증
다음 검증을 완료했다.
```bash
node --check scripts/mcp_bridge.mjs
npm run lint
curl -sS -X POST http://127.0.0.1:3002/api/re-auth
curl -sS -X POST http://127.0.0.1:3002/api/check-connection
```
결과:
- `/api/re-auth`: `success: true`
- `/api/check-connection`: `success: true`
또한 `/api/re-auth``/api/check-connection`을 동시에 호출해도 둘 다 성공하는 것을 확인했다.
## 운영 메모
이제 인증이 풀린 상태에서 NotebookLM MCP 호출이 인증 오류를 반환하면 브리지가 다음 순서로 자동 복구한다.
1. MCP의 `refresh_auth` 실행
2. 실제 `notebook_list` 호출로 인증 유효성 검증
3. 실패 시 MCP 프로세스 재시작 후 재검증
4. 그래도 실패하면 `notebooklm-mcp-auth` CLI 실행
5. 인증 캐시 정리 후 MCP 재시작 및 실제 호출 검증
NotebookLM 브라우저 세션이 완전히 로그아웃된 상태라면 자동 CLI도 브라우저 로그인을 요구할 수 있다. 이 경우 사용자가 열린 NotebookLM [[Chrome|Chrome]] 창에서 로그인만 해두면 이후 자동 복구가 다시 이어질 수 있다.
@@ -1,84 +0,0 @@
# Datacollector NotebookLM Connection Guard and MCP Restart Fix
Date: 2026-04-25 21:02:35 KST
Project: Datacollector
[[Repository|Repository]]: `/Volumes/Data/project/Antigravity/Datacollector`
## Summary
실행 중 NotebookLM 연결 체크가 500 에러를 반환한 뒤에도 미션이 계속 시작되어 Local LM fallback으로 넘어가고, 결국 `Local LM returned an empty or invalid response` 에러가 발생했다.
또한 브리지의 MCP 재시작 로직에서 자동 재시작과 수동 재시작이 겹쳐 여러 `notebooklm-mcp` 프로세스가 남는 문제가 확인되었다.
## Observed Errors
브라우저 콘솔:
```text
:3000/favicon.ico 404 (Not Found)
127.0.0.1:3002/api/check-connection 500 (Internal Server Error)
```
앱 로그:
```text
NotebookLM 연결 실패: 인증 자동 복구 실패...
GENERAL MODE
ENGINE ERROR Local LM returned an empty or invalid response.
```
## Root Causes
1. `testNotebookLmConnection()`이 성공 여부를 반환하지 않았다.
2. `handleStart`, `handleResume`, `handleGlobalResume`이 연결 실패 후에도 그대로 `running` 상태로 넘어갔다.
3. `restart()`가 MCP 프로세스 종료 이벤트를 기다리지 않고 바로 새 프로세스를 띄울 수 있었다.
4. `close` 이벤트의 자동 재시작이 수동 재시작과 겹쳐 MCP 하위 프로세스가 누적될 수 있었다.
5. favicon 파일이 없어서 브라우저가 `/favicon.ico` 기본 요청을 404로 표시했다.
## Changes Made
수정 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/[[Scripts|Scripts]]/mcp_bridge.mjs`
- `/Volumes/Data/project/Antigravity/Datacollector/src/components/AgentDashboard.tsx`
- `/Volumes/Data/project/Antigravity/Datacollector/index.html`
추가 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/public/favicon.svg`
핵심 변경:
- `testNotebookLmConnection()``Promise<boolean>`을 반환하도록 변경
- NotebookLM 연결 실패 시 신규 미션 시작, 개별 재개, 전체 재개를 보류
- 연결 실패 후 Local LM fallback으로 자동 진행되는 흐름 차단
- MCP 프로세스를 종료할 때 `close` 이벤트를 기다리는 `_stopCurrentProcess()` 추가
- 재시작 중 자동 재시작이 중복 실행되지 않도록 제어
- 재시작 테스트 후 MCP 하위 프로세스가 하나만 남는지 확인
- SVG favicon 추가 및 `index.html`에 명시
## Verification
실행한 검증:
```bash
node --check scripts/mcp_bridge.mjs
npm run lint
npm run build
npm run bridge
curl -s http://127.0.0.1:3002/api/health
curl -s -X POST http://127.0.0.1:3002/api/restart
```
검증 결과:
- 브리지 문법 체크 통과
- TypeScript 타입체크 통과
- Vite 빌드 통과
- 브리지 시작 성공
- `/api/health` 응답 정상
- `/api/restart``notebooklm-mcp` 프로세스가 하나만 남는 것 확인
## [[Opera|Opera]]tional Note
현재 실행 중이던 오래된 브리지와 누적된 MCP 하위 프로세스는 종료했다.
앱은 다시 실행해야 새 브리지 로직이 적용된다.
@@ -1,70 +0,0 @@
# Datacollector NotebookLM Progress Visibility and Auth Diagnosis
Date: 2026-04-25 21:17:24 KST
Project: Datacollector
[[Repository|Repository]]: `/Volumes/Data/project/Antigravity/Datacollector`
## Summary
사용자가 UI에서 `NotebookLM 연결 상태 점검 중...` 로그만 반복되고 실제 진행 상황을 알 수 없다고 보고했다.
확인 결과 앱이 프로젝트 생성 단계까지 가지 못하고 있었으며, 원인은 NotebookLM 연결 확인 단계에서 MCP 인증이 만료 상태로 판단되기 때문이었다.
## Observed [[State|State]]
확인한 상태:
- Vite 서버 `3000` 실행 중
- MCP Bridge 서버 `3002` 실행 중
- `notebooklm-mcp` 프로세스 실행 중
- `/api/health` 응답 가능
- `/api/check-connection`은 NotebookLM 인증 만료 오류 반환
브리지 로그상 자동 인증 CLI는 [[Chrome|Chrome]]을 열고 로그인 및 토큰 추출까지 수행했다.
그러나 MCP 서버는 이후에도 `Authentication expired`로 판단하여 NotebookLM notebook list 호출에 실패했다.
## Changes Made
수정 파일:
- `/Volumes/Data/project/Antigravity/Datacollector/[[Scripts|Scripts]]/mcp_bridge.mjs`
- `/Volumes/Data/project/Antigravity/Datacollector/src/components/AgentDashboard.tsx`
핵심 변경:
- MCP 초기화 타임아웃 추가: `MCP_INIT_TIMEOUT_MS`
- NotebookLM 연결 확인 타임아웃 추가: `MCP_HEALTH_TIMEOUT_MS`
- `/api/health`에 상세 상태 추가
- `initialized`, `processRunning`, `processPid`, `pendingRequests`, `authStatus` 노출
- 인증 CLI 진행 단계(`starting`, `running`, `restarting`, `success`, `failed`) 추적
- UI 연결 점검 중 5초마다 Bridge/MCP/auth 진행 상태 로그 출력
- 중복 연결 점검 요청은 기존 Promise를 재사용하도록 변경
## Verification
실행한 검증:
```bash
node --check scripts/mcp_bridge.mjs
npm run lint
npm run build
curl -sS --max-time 5 http://127.0.0.1:3002/api/health
curl -sS --max-time 25 -X POST -H 'Content-Type: application/json' -d '{}' http://127.0.0.1:3002/api/check-connection
```
검증 결과:
- 브리지 문법 체크 통과
- TypeScript 타입체크 통과
- Vite 빌드 통과
- Bridge/MCP 프로세스는 실행됨
- NotebookLM 연결 확인은 인증 만료 오류로 실패
## Current Diagnosis
현재 문제는 앱 실행이나 Bridge 연결 문제가 아니라 NotebookLM MCP 인증 상태 문제다.
자동 인증 CLI가 토큰을 저장해도 MCP 서버가 계속 만료로 판단하므로, 다음 단계에서는 NotebookLM MCP 패키지의 인증 저장 형식 또는 권장 인증 방식(`--file` 모드 등)을 확인해야 한다.
## [[Opera|Opera]]tional Note
확인용으로 실행했던 Bridge/Vite/MCP 프로세스는 종료했다.
새 진행 상태 로그를 보려면 앱을 `run_mac.command`로 다시 실행해야 한다.
@@ -1,173 +0,0 @@
# Skybound Core Gameplay Rebalance and [[Purpose|Purpose]] Reset
**Date**: 2026-04-25
**Project**: Skybound Protocol
**Author**: Codex
**Status**: Raw corrective gameplay pass after balance regression
## 1. User Playtest Feedback
The previous balance pass made the game worse.
Observed issues:
- TAC Level Up triggered repeatedly and too quickly.
- Campaign and Blitz did not communicate a clear purpose.
- It was unclear whether the player should dodge bullets, collect upgrades, survive waves, or simply idle.
- Standing near the center could clear the stage with little interaction.
- Skill choice did not feel strategic because almost any pickup worked.
- The foundation felt like it had grown without a clear gameplay plan.
## 2. Diagnosis
The previous pass overcorrected toward reward frequency and enemy density.
Main problems:
- initial EXP requirement was too low
- EXP gem values were too high
- level-up carryover allowed too much momentum
- no cooldown existed between TAC Level Up [[Events|Events]]
- base magnet radius was too generous
- base damage multiplier was too high
- weapon cooldowns became too generous
- enemy caps became too high for the current combat model
- enemies were too weak for the amount of automatic player damage
The result was a reward flood without enough danger, movement, or tactical pressure.
## 3. New Gameplay Purpose
Skybound should not be a pure bullet hell and should not be an idle auto-clear game.
The intended player loop should be:
1. Survive incoming enemy formations and hazard pressure.
2. Move deliberately to collect EXP gems and supply rewards.
3. Choose upgrades that solve the current pressure pattern.
4. Build toward synergies and evolutions.
5. Enter boss or spike phases with a build that feels earned.
The main fun should come from:
- movement under pressure
- risk-reward EXP collection
- tactical skill choices
- visible power growth
- stage pressure that asks for different answers
The player should not be able to win reliably by standing still.
## 4. Corrective Fixes Applied
### TAC Level Up Flood Control
Applied:
- initial required EXP increased from `45` to `90`
- normal enemy EXP reduced from `7` to `4`
- elite EXP reduced from `32` to `20`
- level-up multiplier increased to `1.42 / 1.48 / 1.55 / 1.62`
- added a `360 frame` TAC Level Up lockout after each level-up
- EXP carryover is capped to `35%` of the next requirement
Expected result:
- level-up moments become meaningful beats
- no rapid-fire modal spam
- players must keep playing between upgrades
### Movement Incentive
Applied:
- base magnet radius reduced from `180` to `90`
- magnet passive now adds `35` per level instead of `60`
Expected result:
- EXP collection requires movement
- standing still misses more progression
- magnet becomes a strategic comfort/passive choice rather than free global collection
### Idle-Clear Reduction
Applied:
- base effective damage reduced from `1.5` to `1.0`
- damage passive now provides growth from deliberate investment
- several weapon cooldowns were pulled back from the previous overly generous pass
- Nova Burst was returned closer to a periodic tactical tool rather than constant auto-clear
Expected result:
- early weapons no longer erase all pressure automatically
- skill investment matters more
- AoE tools help but do not replace positioning
### Enemy Pressure Recentered
Applied:
- hard enemy cap reduced from `90` to `56`
- phase caps reduced from the previous overcorrection
- enemy HP increased from the previous too-low values
- enemies enter deeper into the playfield
- enemy speed and bullet pressure were slightly restored
- procedural spawn cadence reduced from the flood [[State|State]]
Expected result:
- fewer meaningless bodies
- enemies apply actual positional pressure
- player must dodge, reposition, and collect intentionally
## 5. Design Rule Going Forward
Future balance changes should follow this rule:
Do not increase rewards unless a matching risk or movement requirement exists.
Examples:
- faster level-up needs harder collection or less carryover
- more enemies need weaker auto-clear or stronger enemy pathing
- stronger skills need clearer spike counters or enemy [[Behavior|Behavior]]s
- more pickups need better pickup [[Affordance|Affordance]] and danger around pickup zones
## 6. Changed Runtime Paths
Important changed paths:
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/store/useGameStore.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/SpawnerSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/CombatTimeline.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/balance.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/weaponBehaviors.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ModularWeaponSystem.ts`
## 7. Verification
Production build completed successfully with:
```bash
npm run build
```
The existing `/sprites/player.png` static asset warning remains non-[[Blocking|Blocking]].
## 8. Next Necessary Design Work
This corrective patch stabilizes the worst problems, but the project still needs a stronger core design pass.
Recommended next work:
- define Campaign as objective-based stages with unique pressure patterns
- define Blitz as score/survival mode with explicit risk-reward scoring
- add clear stage objectives to HUD
- add enemy archetypes that force movement differently
- add pickup-risk zones so rewards are not free
- review every skill for role identity: damage, crowd control, defense, mobility, economy
@@ -1,103 +0,0 @@
# Skybound Player Airframe and 8 Stage Boss Continuity Rework
작성일: 2026-04-25 09:51 KST
## 요청 요약
- 사용자 기체가 엔진에서 그린 도형 조립처럼 보여 시각적 완성도가 낮아 보이는 문제를 개선한다.
- Stage 1 클리어 후 Stage 2로 넘어가는 흐름이 결과 화면으로 끊겨 게임이 단절되는 문제를 개선한다.
- Aero Fighters처럼 보스를 처치하고 같은 런 안에서 다음 스테이지로 자연스럽게 이어지는 구조를 만든다.
- 총 8개 스테이지를 유지하고, 스테이지가 올라갈수록 난이도가 올라가도록 보스 HP, 파츠, 패턴을 재조정한다.
- 각 스테이지 보스가 서로 다른 공격 패턴을 체감할 수 있도록 실행부를 보강한다.
## 확인한 문제
### 플레이어 기체 렌더링
- `GameRenderer.renderPlayer()`에서 플레이어 스프라이트 위에 랜덤 원형 엔진 글로우를 직접 그려서, 기체 뒤쪽이 매 프레임 흔들리는 임시 도형처럼 보였다.
- `renderWeaponAttachments()`에서 일부 장착 무기를 `fillRect`, `strokeRect`, 랜덤 원형 플래시로 그려서 톤앤매너에 맞는 완성형 파츠가 아니라 디버그 박스처럼 보일 수 있었다.
- 특히 Hyper Sonic Vulcan, Gatling fallback, Missile Pod fallback이 사용자 기체 실루엣과 잘 섞이지 않았다.
### 스테이지 전환
- 보스 처치 후 `STAGE_CLEAR`가 되고, 300프레임 뒤 `BOSS_ACTION NEXT_STAGE` 이벤트가 발생한다.
- 기존 `useGameEngine`은 이 이벤트를 곧바로 `finishMission('CLEAR')`로 연결했다.
- 그 결과 Standard 캠페인에서도 Stage 1 보스 처치 후 결과 화면으로 끊기고, 다음 스테이지는 별도 런처럼 느껴졌다.
### 보스 패턴
- `bossActions.ts`에는 Stage 1부터 Stage 8까지 액션 테이블이 있다.
- 하지만 `BossSystem.executePattern()`은 일부 액션만 처리하고 있었기 때문에, 실제 전투에서는 많은 액션이 기본 단발 탄으로 떨어질 수 있었다.
- `StageDirectorSystem.instantiateBoss()`의 보스 파츠 turretId가 `T-CORE`, `T-WING`, `T-HEAVY`처럼 실제 `TURRET_CATALOG`에 없는 값이라 파츠 포탑이 의도대로 발사되지 않을 수 있었다.
- 기존 보스 HP는 Stage 2부터 `5000 * currentStage`로 급격히 올라가 캠페인 커브가 자연스럽지 않았다.
## 적용한 변경
### 플레이어 기체 완성도 개선
- 플레이어 엔진 글로우를 랜덤 원형에서 고정된 마기테크 추진 플룸으로 변경했다.
- 스프라이트 크기를 72px에서 78px로 약간 키워 중심 기체의 존재감을 높였다.
- `drawMagitechPod()` 헬퍼를 추가해 장착 무기를 작은 마기테크 포드 형태로 통일했다.
- Vulcan, Gatling fallback, Missile Pod fallback을 박스 도형 대신 다크 블루 메탈 바디, 시안/옐로/핑크 액센트, 라운드 포드 실루엣으로 렌더링한다.
- 장착 파츠의 랜덤 플래시를 줄이고 프레임 기반 pulse로 바꿔 덜 튀고 더 의도적으로 보이게 했다.
### 연속 캠페인 전환
- Standard 캠페인에서 Stage 1-7 보스 처치 후 `finishMission`을 호출하지 않고, 같은 엔진 런 안에서 다음 스테이지로 전환하도록 변경했다.
- 전환 시 다음 작업을 수행한다.
- `currentStage` 증가
- `campaignStageIndex` 저장
- `StageDirectorSystem.advanceToStage()`로 새 타임라인 로드
- 활성 총알, 적, 파티클 풀 정리
- 스포너 큐 초기화
- 보스, 탄막, hazard, airdrop, exp gem, vortex 정리
- `INTRO` 페이즈로 재시작
- 체력 25% 회복과 120프레임 무적 부여
- Stage 안내 텍스트와 HQ comms 출력
- Stage 8 보스 처치 시에는 `GAME_COMPLETE`로 결과 화면에 진입한다.
- Blitz 모드는 기존처럼 단일 전투 클리어로 유지한다.
### 8스테이지 보스 커브
- 보스 HP를 선형 폭증에서 완만한 곡선형 성장으로 변경했다.
- Stage 1은 낮게 시작하고, Stage 8은 누적 성장과 보스 패턴 난이도를 고려해 높은 난이도를 갖도록 설계했다.
- 보스 파츠 HP도 같은 stage curve를 사용해 코어, 날개, 포탑이 함께 성장한다.
- 각 스테이지에 실제 `TURRET_CATALOG`에 존재하는 turretId loadout을 지정했다.
### 보스 패턴 실행 보강
- 다음 액션들이 실제 탄막/기믹으로 실행되도록 매핑했다.
- `FAN_PART`, `DASH_PART`: 부채꼴 조준 사격
- `SIDE_WAVE`: 좌우 측면 웨이브
- `ZONE_BOMB`: 안전 구역 압박과 링 탄막
- `WALL_WAVE`: 틈이 있는 벽 형태 탄막
- `MISSILE_BARRAGE`, `HOMING_CHASE`: 유도성 탄막
- `CROSS_CHASE`: 네 방향 교차 추격 탄
- `SPIRAL_WEB`, `REVOLVING_FLAME`: 나선 탄막
- `BURST_SPLITTER`: 분열형 부채 탄
- `GEAR_STORM`: 고밀도 나선과 링 조합
- `PRECISION_LOCK`, `SNIPE_GRID`, `LASER_AIM`, `LASER_SWEEP`: 크로스헤어 기반 고속 압박
- `TELEPORT_STRIKE`: 보스 위치 변경 후 기습 사격
- `GIMMICK_PULSE`, `CC_REVERSE`, `ZONE_COLLAPSE`: 중력장/페이즈존 기믹과 링 탄막
- `ULTIMATE_SYMPHONY`: 기존 고난도 복합 패턴 유지
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/GameRenderer.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/hooks/useGameEngine.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/StageDirectorSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/BossSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/EntityManager.ts`
## 검증
- `npm run build` 성공
- Vite 경고: `/sprites/player.png [[Reference|Reference]]d in /sprites/player.png didn't resolve at build time`
- 위 경고는 기존 런타임 경로 관련 경고이며 이번 변경으로 인한 빌드 실패는 아니다.
## 후속 플레이테스트 포인트
- Stage 1 보스 처치 후 결과 화면 없이 Stage 2 INTRO로 자연스럽게 이어지는지 확인한다.
- Stage 8 보스 처치 후 `GAME_COMPLETE` 결과로 진입하는지 확인한다.
- 장착 무기 파츠가 기체와 과하게 분리되어 보이지 않는지 확인한다.
- Stage 3 이후 `ZONE_BOMB`, `WALL_WAVE`, `HOMING_CHASE`, `PRECISION_LOCK` 계열이 회피 목적을 명확히 만드는지 확인한다.
@@ -1,75 +0,0 @@
# Skybound Skill Concept and Hangar Layout Overlap Fix
작성일: 2026-04-25 10:09 KST
## 요청 요약
- 스킬 업그레이드 후 화면에 긴 라이트 기둥만 보이는 문제가 있어 스킬 개념과 연출을 수정한다.
- HUD/UI 관점에서 왼쪽에 여러 UI가 겹쳐 나오는 문제가 있어 필요하면 전체적으로 재설계한다.
## 확인한 문제
### Hyper-Sonic Vulcan 컨셉 불일치
- `Hyper-Sonic Vulcan`은 이름상 고속 벌컨/캐논 계열인데 실제 구현은 영구 지속되는 긴 레이저 빔이었다.
- `GameRenderer`가 플레이어 기준으로 화면 끝까지 이어지는 두꺼운 시안 빔을 그려서, 스킬이 무기라기보다 긴 조명처럼 보였다.
- `ModularWeaponSystem.updateHyperLaser()`도 라인 판정으로 지속 데미지를 넣고 있어 플레이어가 발사/탄막을 체감하기 어려웠다.
### Hangar UI 겹침
- `HangarOverlay.tsx`에서 `UPGRADE``PASS` 탭 콘텐츠가 오른쪽 `craft-area` 패널 밖에 렌더링되고 있었다.
- 그 결과 [[CSS Grid|CSS Grid]]의 세 번째 아이템처럼 배치되어 왼쪽 패널/재료 영역과 겹쳐 보였다.
- 특히 `UPGRADE` 탭 선택 시 `PERMANENT UPGRADES` 콘텐츠가 왼쪽 재료 패널 위로 올라오는 문제가 발생했다.
### 전투 보상 텍스트 겹침
- 적 처치 보상 텍스트가 화면 가장자리에서 생성될 경우 `TechMats`, `+TAC` 같은 텍스트가 잘리거나 서로 겹쳐 보일 수 있었다.
## 적용한 변경
### Twin Arc Vulcan으로 스킬 컨셉 변경
- `HYPER_SONIC_VULCAN` 메타데이터 이름을 `Twin Arc Vulcan`으로 변경했다.
- 설명도 `Twin magitech cannons fire rapid piercing arc rounds.`로 바꿔 실제 플레이 감각과 맞췄다.
- 기존의 영구 레이저 빔 컨셉을 제거하고, 전방 관통 아크 탄환을 빠르게 발사하는 무기로 재설계했다.
- 플레이어 좌우 포드에서 3갈래 관통탄을 빠르게 발사해 “벌컨 업그레이드” 느낌을 강화했다.
- 스킬이 화면을 덮는 긴 빛이 아니라, 방향성과 탄막 밀도가 있는 공격으로 보이게 했다.
### 긴 라이트 렌더링 제거
- `GameRenderer`의 full-screen beam `fillRect()` 렌더링을 제거했다.
- 대신 기체 앞쪽 포드에 짧은 muzzle bloom과 짧은 시안 streak만 표시하도록 변경했다.
- 화면 전체를 가리는 시각 노이즈를 줄이고, 실제 공격은 projectile 렌더링이 담당하게 했다.
### Hangar 탭 레이아웃 수정
- `UPGRADE``PASS` 탭 콘텐츠를 오른쪽 `craft-area` 내부로 이동했다.
- 이제 탭 콘텐츠가 왼쪽 `Airframe Telemetry`/`Materials` 패널과 겹치지 않는다.
- 기존 스타일을 유지하면서 구조적 렌더링 오류를 먼저 제거했다.
### Floating Text 안전 영역 처리
- `ctx.spawnText()`에서 텍스트 생성 위치를 화면 안전 영역 안으로 clamp한다.
- 왼쪽 끝/오른쪽 끝에서 적이 죽어도 보상 텍스트가 화면 밖으로 잘리거나 HUD 영역에 과하게 겹치는 현상을 줄였다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ModularWeaponSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/GameRenderer.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/evolutions.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/weapon[[Behavior|Behavior]]s.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/HangarOverlay.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/hooks/useGameEngine.ts`
## 검증
- `npm run build` 성공
- Vite 경고: `/sprites/player.png [[Reference|Reference]]d in /sprites/player.png didn't resolve at build time`
- 위 경고는 기존 런타임 경로 경고이며 이번 변경으로 인한 빌드 실패는 아니다.
## 후속 플레이테스트 포인트
- Gatling 진화 후 더 이상 긴 레이저 기둥이 보이지 않는지 확인한다.
- `Twin Arc Vulcan`이 빠른 관통 탄막 무기로 체감되는지 확인한다.
- Hangar에서 `UPGRADES`, `EVENT PASS` 탭 선택 시 왼쪽 패널과 콘텐츠가 겹치지 않는지 확인한다.
- 전투 보상 텍스트가 화면 가장자리에서 잘리지 않는지 확인한다.
@@ -1,105 +0,0 @@
# Skybound Tac EXP Direct Kill and UI Productization Pass
작성일: 2026-04-25 10:01 KST
## 요청 요약
- Tac Level 경험치는 적기를 처치했을 때 바로 획득하게 한다.
- 바닥에 경험치 파티클/젬이 떨어져 화면을 어지럽히지 않게 한다.
- 너무 빠른 레벨업으로 난이도 밸런스가 무너지는 문제를 완화한다.
- Hangar, HUD, Tac Level Up 등 아직 남아 있는 예전 UI 톤을 Stylized Casual Magitech 톤앤매너에 맞게 통일한다.
- `THRUST_OUTPUT`처럼 작동하지 않거나 내부 시스템 문자열처럼 보이는 UI 문구를 상품성 있게 정리한다.
## 확인한 문제
### Tac EXP
- `CombatSystem`이 적 사망 시 `spawnExpGem()`을 호출해 바닥에 경험치 젬을 생성하고 있었다.
- `ProgressionSystem`은 바닥 젬의 이동, 자석 흡수, 수집을 통해 경험치를 지급했다.
- 적 밀도가 올라갈수록 젬이 많이 쌓이고, 화면 가독성과 레벨업 속도 모두 불안정해질 수 있었다.
- 기존 젬 값은 일반몹/엘리트몹 기준으로 레벨업을 빠르게 밀어 올리는 구조였다.
### HUD 문구
- `SYSTEM_ACTIVE`, `TAC_LEVEL`, `HIGH_SCORE_SYNC`, `COMBO_LINK`, `ENERGY_CELL`, `LOCK_ON`, `HEAT_SIG`, `SHIELD_OS`, `THRUST_OUTPUT` 같은 내부 변수명 스타일 문구가 사용자에게 그대로 노출되고 있었다.
- `THRUST_OUTPUT``dodgeCooldownPct`를 읽지만 엔진에서 값을 갱신하지 않아 실질적으로 반응하지 않는 상태였다.
### Hangar UI
- 장비 카드가 빈 박스처럼 보이며 아이템명/레벨/스탯 정보가 충분히 드러나지 않았다.
- 탭 이름과 슬롯 이름이 기능적이지만 상품 화면처럼 자연스럽지는 않았다.
- 전체 스타일이 이전의 얇은 선, 어두운 반투명 박스 중심이라 현재 게임의 굵은 외곽선/밝은 마법 액센트 톤과 어긋났다.
## 적용한 변경
### Tac EXP 직접 지급
- `CombatSystem`에서 적 사망 시 더 이상 `spawnExpGem()`을 호출하지 않는다.
- 대신 `ctx.grantTacExp()`를 통해 처치 즉시 경험치를 지급한다.
- 일반 적: `+1 TAC`
- 엘리트 적: `+5 TAC`
- 미드 보스: `+16 TAC`
- 엘리트 이상만 짧은 `+TAC` 텍스트 피드백을 표시해 화면 노이즈를 줄였다.
- 바닥 경험치 젬은 신규 생성되지 않으므로, 플레이 중 먹을 수 없는 파란 점/구슬이 쌓이는 문제가 사라진다.
### 레벨업 속도 완화
- `ProgressionSystem.grantExp()`를 추가해 직접 경험치 지급과 기존 젬 수집 지급을 한 곳에서 처리한다.
- Spike 전 EXP 부스트는 최대 `x1.25`로 제한했다.
- 기존 레벨업 lockout과 carryover cap은 유지해 연속 레벨업 폭주를 방지한다.
### HUD 상품성 개선
- `HIGH_SCORE_SYNC``Best Run`
- `SYSTEM_ACTIVE``Falcon Online`
- `TAC_LEVEL``Tactical Level`
- `THRUST_OUTPUT``Afterburner`
- `ENERGY_CELL``Hull Core`
- `COMBO_LINK``Chain Bonus`
- `LOCK_ON``Lock-On`
- `HEAT_SIG``Heat Trace`
- `SHIELD_OS``Guard Field`
- 페이즈 표시도 `BOSS_WARNING` 같은 내부 enum 대신 `Boss Incoming`, `Horde Surge`, `Route Secured` 같은 플레이어용 문구로 매핑했다.
- 엔진에서 `setDodgeCooldownPct()`를 실제 dodge 상태에 맞게 갱신해 Afterburner 게이지가 부스트 중 반응하도록 연결했다.
### Hangar UI 톤 통일
- Hangar 배경과 패널을 Stylized Casual Magitech 톤으로 보강했다.
- 굵은 네이비 외곽선, 청록/민트/골드 마법 액센트, 둥근 카드, 명확한 hover 피드백을 적용했다.
- 장비 카드에 아이템 타입, 이름, 레벨, ATK, HP가 보이도록 개선했다.
- 탭 이름을 `LOADOUT`, `SYNTHESIS`, `SALVAGE`, `ASTRAL FORGE`, `UPGRADES` 등 더 자연스러운 메뉴명으로 바꿨다.
- 빈 슬롯 문구를 `NO MODULE`에서 `Available mount`로 바꿨다.
- `SYSTEM MOUNTS`, `MODULE [[Storage|Storage]]`를 각각 `Mount Bays`, `Module Storage`로 정리했다.
### Level Up 모달 문구 개선
- `TAC LV`, `TAC LEVEL UP!`, `SELECT TACTICAL ENHANCEMENT` 중심의 시스템 문자열 느낌을 줄였다.
- 일반 레벨업: `Tactical Upgrade`
- 시작 선택: `Choose First Weapon`
- 보급 선택: `Emergency Supply`
- 카드 문구도 `NEW ACQUISITION`에서 `New module`로 완화했다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/hooks/useGameEngine.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/HUDOverlay.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/HangarOverlay.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/HangarOverlay.css`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/LevelUpModal.tsx`
## 검증
- `npm run build` 성공
- Vite 경고: `/sprites/player.png [[Reference|Reference]]d in /sprites/player.png didn't resolve at build time`
- 위 경고는 기존 런타임 경로 경고이며 이번 변경으로 인한 빌드 실패는 아니다.
- 주요 내부 문자열 검색 결과, 요청에서 지적된 `SYSTEM_ACTIVE`, `THRUST_OUTPUT`, `TAC_LEVEL`, `HIGH_SCORE_SYNC`, `COMBO_LINK`, `ENERGY_CELL`, `LOCK_ON`, `HEAT_SIG`, `SHIELD_OS`는 현재 게임 UI 코드에서 제거되었다.
## 후속 플레이테스트 포인트
- 적 처치 후 바닥에 경험치 젬이 신규로 생성되지 않는지 확인한다.
- 일반몹을 많이 잡아도 Tac Level이 연속 폭주하지 않는지 확인한다.
- Afterburner 게이지가 회피/부스트 중 시각적으로 반응하는지 확인한다.
- Hangar 장비 카드가 더 이상 빈 회색 박스처럼 보이지 않고 아이템 정보를 명확히 보여주는지 확인한다.
@@ -1,116 +0,0 @@
# Skybound Vampire Survivors Loop and Stage Curve Preparation
작성일: 2026-04-25 23:52 KST
## 요청 요약
- Skybound가 뱀파이어 서바이벌 계열 게임처럼 느껴지도록 재미 요소와 스테이지별 레벨 구조를 준비한다.
- 단순히 적을 많이 내보내는 것이 아니라, 성장 선택, 밀도 상승, 진화 완성, 보스 체크포인트가 자연스럽게 이어지도록 만든다.
## 핵심 방향
Skybound는 탑다운 생존 슈터이지만, 기존 구조는 스테이지 시간이 짧고 보스 진입이 빨라 빌드가 완성되기 전에 전투가 끊기는 문제가 있었다. 뱀서류 재미를 만들려면 다음 루프가 안정적으로 반복되어야 한다.
1. 초반: 첫 무기 선택 후 약한 적을 많이 처치하며 빠르게 1-2회 성장한다.
2. 중반: 적 밀도와 엘리트 압박이 올라가며 광역/관통/방어 선택의 의미가 생긴다.
3. 후반: 스웜과 미니보스가 들어오며 빌드 조합과 진화 무기가 필요해진다.
4. 보스: 완성된 빌드가 제대로 작동하는지 검증한다.
5. 다음 스테이지: 같은 빌드를 이어가되 적 밀도, 패턴, 보스 기믹이 상승한다.
## 적용한 변경
### 8스테이지 Survivor 프로필 추가
`CombatTimeline.ts``SURVIVOR_STAGE_PROFILES`를 추가했다. 각 스테이지는 아래 정보를 가진다.
- 스테이지 이름
- 스테이지 길이
- 기본 난이도 배율
- 동시 적 수 기준
- 스폰 템포
- 오프닝 웨이브
- 압박 엘리트 웨이브
- 스웜 웨이브
- 클라이맥스 엘리트 웨이브
- 미니보스 체크포인트
### 스테이지별 구조
- Stage 1 `First Contact`: 첫 무기와 기본 생존 학습
- Stage 2 `Fast Lanes`: 빠른 적과 이동 압박
- Stage 3 `Ruined Circuit`: 혼합 편대와 엘리트 압박
- Stage 4 `Crossfire Grid`: 길막/라인 클리어 압박
- Stage 5 `Magma Forge`: 고밀도 스웜 시작
- Stage 6 `Storm Foundry`: 빌드 완성 요구
- Stage 7 `Arcane Collapse`: 진화 무기 권장
- Stage 8 `Final Singularity`: 완성 빌드 검증
### 스테이지 시간 조정
기존 Standard 스테이지는 약 165초부터 시작해 빌드업 시간이 부족했다. 새 구조에서는 Stage 1이 240초, Stage 8이 420초까지 증가한다.
이렇게 하면 플레이어는 한 스테이지 안에서 다음 리듬을 경험할 수 있다.
- 0-25%: 세팅과 첫 성장
- 25-48%: 엘리트 압박
- 48-72%: 스웜 압박
- 72%-보스 전: 클라이맥스와 미니보스
- 마지막 35초 전후: 보스전 진입
### 스폰 밀도 조정
- 적 하드캡을 56에서 76으로 올렸다.
- 스웜 배치 단위를 6에서 8로 올렸다.
- 기본 절차 스폰 간격을 96프레임에서 84프레임으로 줄였다.
목표는 “가만히 있어도 클리어”가 아니라, 점점 밀려오는 압박을 움직임과 빌드 선택으로 해결하게 만드는 것이다.
### Tac EXP 커브 조정
바닥 EXP 젬을 다시 뿌리지는 않고, 처치 즉시 Tac EXP를 지급하는 현재 방향을 유지했다. 다만 뱀서류 성장 리듬을 만들기 위해 처치 경험치를 조정했다.
- 일반 적: `+2 TAC`
- 엘리트 적: `+10 TAC`
- 미드보스: `+30 TAC`
초기 요구 EXP는 `90`에서 `80`으로 낮췄다. 대신 레벨업 후 초과 EXP carryover는 25%만 유지해 연속 레벨업 폭주는 막는다.
레벨 요구량 배율은 아래처럼 조정했다.
- Level 1-4: `x1.34`
- Level 5-8: `x1.42`
- Level 9-14: `x1.52`
- Level 15+: `x1.62`
## 설계 의도
이번 변경은 “Vampire Survivors의 재미”를 다음 요소로 해석했다.
- 적은 점점 많아진다.
- 플레이어는 더 자주 선택하고 강해진다.
- 선택에는 빌드 방향성이 있다.
- 중반 이후에는 광역, 관통, 방어, 기동 중 최소 하나가 부족하면 압박을 느낀다.
- 보스는 단절된 엔딩이 아니라 빌드 검증 구간이다.
- 다음 스테이지는 새 게임이 아니라 이전 빌드의 확장 시험이다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/CombatTimeline.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/SpawnerSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/store/useGameStore.ts`
## 검증
- `npm run build` 성공
- Vite 경고: `/sprites/player.png [[Reference|Reference]]d in /sprites/player.png didn't resolve at build time`
- 위 경고는 기존 런타임 경로 경고이며 이번 변경으로 인한 빌드 실패는 아니다.
## 후속 작업 제안
- 각 스테이지별 고유 몬스터 역할 비중을 더 명확히 분리한다.
- 스테이지별 보스 패턴을 현재보다 더 강하게 차별화한다.
- 진화 무기별 화면 가독성과 성능을 플레이테스트로 검증한다.
- 미니보스 처치 시 보물상자/카드 선택 보상을 확정 지급하는 구조를 추가하면 뱀서류 보상감이 더 강해진다.
@@ -1,123 +0,0 @@
# Skybound Enemy Motion Damage Pressure and Projectile Visual Pass
작성일: 2026-04-26 12:46 KST
## 요청 요약
- Stage 1 적기의 이동이 어디에 낀 것처럼 바들바들 떨리는 문제를 개선한다.
- 적 공격 데미지가 사용자 Tac Level에 정비례해서 오르는 느낌이 아니라, 소폭만 상승하도록 조정한다.
- 사용자 기체의 일반 공격 탄환과 Gatling 탄환이 단순 렌더링 도형처럼 보여 아쉬운 문제를 개선한다.
- 스킬과 탄환의 비주얼을 Skybound의 Stylized Casual Magitech 톤앤매너에 맞춰 더 상품성 있게 다듬는다.
## 핵심 문제
### 적 이동 떨림
Stage 1에서 보이는 적기의 떨림은 주로 추적형 AI가 플레이어 근처에서 목표점을 매 프레임 다시 계산하면서 발생했다. 목표를 향해 직선 이동하다가 너무 가까워지면 다음 프레임에 방향이 반대로 튀고, 여기에 회전값도 즉시 플레이어를 향해 바뀌면서 시각적으로 “끼어서 떠는” 것처럼 보였다.
### 적 데미지 상승
적 데미지는 스테이지와 페이즈 압박에 따라 올라가야 하지만, 사용자 Tac Level과 동일한 폭으로 오르면 성장 보상이 무효화된다. 따라서 Tac Level은 적 데미지에 아주 작은 압박 보정만 주는 것이 맞다.
### 플레이어 탄환 비주얼
기본 공격과 Gatling 탄환은 기존 Canvas 사각형/막대 형태가 남아 있어, 현재 게임의 마법공학 기체와 스킬 아이콘 퀄리티에 비해 완성도가 낮게 보였다.
## 적용한 변경
### 적 회전 안정화
적기의 회전을 즉시 목표 각도로 바꾸지 않고 `smoothEnemyRotation`을 통해 보간한다.
이제 적은 플레이어를 향해 부드럽게 회전하며, 근거리에서 회전값이 프레임마다 튀는 현상이 줄어든다.
### 추적형 적 이동 안정화
`chase` 패턴에 속도 보간과 근거리 감속을 추가했다.
- 목표점으로 바로 이동하지 않고 `vx`, `vy`를 보간한다.
- 플레이어와 너무 가까워지면 속도를 줄인다.
- 일정 거리 안으로 들어오면 살짝 밀려나며 겹침을 완화한다.
### 적끼리 겹침 완화
`applyEnemySeparation`을 추가했다. 적이 서로 너무 가까이 붙으면 약하게 밀어내어, 여러 적이 한 점에 몰려 떨리는 문제를 줄인다.
적 종류별 최소 거리도 다르게 적용한다.
- 일반 적: 작은 거리
- 엘리트: 중간 거리
- 미니보스: 더 큰 거리
### 적 데미지 보정 완만화
기존에는 페이즈 난이도 배율이 탄속/데미지에 직접적으로 강하게 반영될 수 있었다. 이제 아래처럼 완만하게 조정했다.
- 탄속은 페이즈 배율을 직접 곱하지 않고 작은 `phaseSpeedPressure`만 반영한다.
- 데미지는 스테이지 커브를 기본으로 하되 `phaseDamagePressure`를 제한적으로 적용한다.
- 사용자 Tac Level은 최대 `+18%`까지만 적 데미지에 반영한다.
의도는 다음과 같다.
- 플레이어가 성장해도 적이 완전히 무력해지지는 않는다.
- 하지만 플레이어 레벨이 올랐다고 적 데미지가 같은 폭으로 따라오지는 않는다.
- 성장 보상은 유지하고, 긴장감만 조금 보강한다.
### 플레이어 탄환 비주얼 개선
기본 탄환, Gatling 탄환, Rayce 탄환, 드론 탄환에 `visualKind`를 부여했다.
추가된 visualKind:
- `arc_bolt`
- `gatling_round`
- `rayce_lance`
- `micro_missile`
- `arc_vulcan`
- `drone_shot`
### Magitech Projectile Renderer 추가
`GameRenderer``renderMagitechProjectile`을 추가했다. 기존 사각형 탄환 대신 아래 요소를 가진 발사체로 렌더링된다.
- 밝은 코어
- 마법공학 외곽 라인
- 발사 방향 꼬리광
- 글로우
- 작은 룬/핀 라인
- 기체/무기별 색상 차이
Gatling은 골드빛 짧은 고속탄, 기본 Falcon 탄은 시안 아크 볼트, Rayce는 마젠타 랜스형 탄환으로 보이게 했다.
## 설계 의도
이번 변경은 조작감과 시각 품질을 동시에 개선하는 작업이다.
적 이동은 “불안정한 버그처럼 보이는 흔들림”이 아니라, 의도된 추적/회피 압박처럼 보여야 한다. 또한 적 데미지는 플레이어 성장과 같은 폭으로 따라오면 안 된다. 플레이어는 강해져야 하고, 적은 그 강함을 무효화하지 않는 선에서 압박을 유지해야 한다.
탄환 비주얼은 Skybound의 가장 자주 보는 이펙트이므로, 단순 도형이 남아 있으면 전체 완성도를 낮춘다. 이번 변경으로 기본 공격도 스킬과 같은 톤의 Magitech 무장처럼 보이게 했다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/GameRenderer.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ModularWeaponSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/PlayerSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/SpawnerSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/Weapon[[Behavior|Behavior]]Engine.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
## 검증
- `npm run build` 성공
- `/sprites/player.png` 경고 없음
- 출력 디렉터리: `dist/23`
## 후속 플레이테스트 체크 포인트
- Stage 1 일반 적이 플레이어 근처에서 바들바들 떨지 않는지 확인한다.
- 적이 겹칠 때 자연스럽게 분산되는지 확인한다.
- Tac Level이 올라가도 적 데미지가 과하게 따라오지 않는지 확인한다.
- Falcon 기본탄과 Gatling 탄환이 사각형 도형이 아니라 마법공학 발사체처럼 보이는지 확인한다.
- Rayce 탄환이 Falcon과 충분히 구분되는지 확인한다.
- 이후 스킬별 전용 Canvas/PNG 이펙트를 더 세분화할지 결정한다.
@@ -1,172 +0,0 @@
# Skybound HP Scarcity and Module Cache Rewards
작성일: 2026-04-26 13:01 KST
## 요청 요약
- Stage 1 플레이 중 하트 HP 회복 아이템이 너무 자주 드롭되어 위기감이 사라지는 문제를 개선한다.
- 초반에는 어느 정도 회복을 주되, 항상 충분하게 주기보다 “조금 아쉬운” 수준으로 조정한다.
- 전투 중 모듈이 자동 지급되어 획득 재미가 떨어지는 문제를 개선한다.
- 보물 상자 혹은 모듈 상자 이미지를 만들고, 사용자 인벤토리에 stacking되게 한다.
- 상자를 열었을 때 모듈 획득 이펙트와 연출을 추가한다.
- 일반 등급은 기본 연출, 상급 이상은 개봉 중 기대감을 줄 수 있는 힌트 연출을 제공한다.
## 핵심 문제
기존 보상 구조는 적 처치 시 장비가 곧바로 `inventory`에 추가되는 방식이었다.
이 구조는 기능적으로는 빠르지만, 사용자가 다음 감각을 느끼기 어렵다.
1. 내가 무언가를 얻었다는 소유감
2. 전투 후 보상을 확인하는 기대감
3. 상자를 열 때 “이번에는 뭐가 나올까” 하는 가챠/루팅 재미
4. 등급별 보상의 차이
또한 하트 드롭은 대량의 적 처치 수와 결합되면서 체력 결핍이 거의 발생하지 않는 상태를 만들었다.
## 적용한 변경
### HP 회복 아이템 희소화
기존에는 적 처치 시 25% 확률로 필드 아이템이 나오고, 그중 일부가 HP 회복 아이템이었다.
변경 후에는 체력 상태와 쿨다운을 기반으로 HP 드롭을 계산한다.
- HP가 82% 이상이면 하트 드롭이 거의 발생하지 않는다.
- HP가 60% 미만일 때부터 하트 확률이 의미 있게 상승한다.
- HP가 35% 미만이면 긴급 회복 가능성을 열어둔다.
- 하트 드롭 후에는 기본 900프레임 쿨다운을 둔다.
- 위기 상황에서는 쿨다운을 480프레임으로 낮춰 완전한 운빨 사망은 줄인다.
- 엘리트와 미니보스는 회복/보상 드롭 가능성이 조금 더 높다.
### 회복량 조정
하트 하나가 체력을 너무 크게 회복하지 않도록 회복량을 낮췄다.
변경 전:
- 필드 하트: 최대 HP의 20%
- 회복 에어드롭: 최대 HP의 40%
변경 후:
- 필드 하트: 최대 HP의 14%
- 회복 에어드롭: 최대 HP의 32%
목표는 “살았다”는 안도감은 주되, 바로 100% 안정권으로 돌아가지 않게 만드는 것이다.
### 자동 모듈 지급 제거
일반 적 처치 시 장비가 직접 지급되는 흐름을 제거했다.
변경 후:
- 일반 적은 장비/모듈 캐시를 지급하지 않는다.
- 엘리트, 미니보스, 보스 보상은 즉시 장비 지급이 아니라 `Module Cache`로 전환된다.
- 캐시는 격납고 인벤토리에 stacking된다.
- 실제 장비는 사용자가 캐시를 열 때 생성된다.
이제 전투 중에는 “보상 상자를 회수했다”는 흐름이 되고, 장비 획득은 격납고에서 별도 개봉 경험으로 분리된다.
### Module Cache 인벤토리 추가
`useGameStore``moduleCaches` 상태와 액션을 추가했다.
추가된 액션:
- `addModuleCache(cache)`
- `openModuleCache(cacheId)`
`openModuleCache`는 캐시의 등급과 클래스 정보를 기반으로 장비를 생성하고, 해당 장비를 `inventory``isNew` 상태로 추가한다.
### Module Cache 이미지 추가
톤앤매너에 맞춘 Stylized Casual Magitech 상자 SVG를 추가했다.
특징:
- 굵은 외곽선
- 시안/라임 마력 코어
- 블루 메탈 케이스
- 골드 띠 장식
- 상자 개봉 UI에서 재사용 가능한 벡터 에셋
추가 파일:
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/module_cache.svg`
### 격납고 Module Cache UI 추가
`HangarOverlay`의 Loadout 탭에 `Module Caches` 섹션을 추가했다.
UI 동작:
- 같은 등급/클래스/출처의 캐시는 하나의 카드로 stacking 표시된다.
- 카드에는 `xN` 카운트가 표시된다.
- Elite Cache, Command Cache, Boss Cache 출처가 표시된다.
- 클릭하면 해당 캐시 1개를 개봉한다.
### 등급별 개봉 연출 추가
캐시 개봉 시 별도 오버레이가 뜨도록 했다.
연출 구성:
- 어두운 배경 블러
- 캐시 중심 이미지
- 등급 색상 기반 발광
- 회전하는 아케인 링
- 작은 마력 스파크
- 개봉 중 힌트 텍스트
- 최종 모듈 이름/타입/스탯 공개
일반 등급은 짧은 기본 개봉으로 처리하고, GOOD 이상은 개봉 중 다음 힌트를 보여준다.
- 모듈 타입 신호
- 보상 출처
- 등급 신호 안정화 문구
이를 통해 상급 이상 상자는 결과 공개 전 기대감을 주는 구조로 만들었다.
## 설계 의도
이번 패스의 목표는 Stage 1의 생존 긴장감과 보상 기대감을 동시에 살리는 것이다.
하트는 플레이어를 완전히 방치하지 않되, 항상 충분하게 주지 않는다.
모듈은 자동 지급에서 상자 개봉으로 바꿔 다음 루프를 만든다.
1. 전투에서 엘리트/보스 처치
2. 모듈 캐시 획득
3. 격납고로 복귀
4. 캐시 stack 확인
5. 캐시 개봉
6. 모듈 획득
7. 장착/합성/분해 선택
이 구조는 Vampire Survivors류의 런 성장과 Survivor.io류의 메타 보상 사이를 이어주는 역할을 한다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/public/sprites/module_cache.svg`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/store/useGameStore.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/StageDirectorSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/HangarOverlay.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/HangarOverlay.css`
## 검증
- `npm run build` 성공
- `/sprites/player.png` 경고 없음
- 출력 디렉터리: `dist/24`
## 후속 플레이테스트 체크 포인트
- Stage 1 초반 하트가 너무 부족해서 불합리하게 느껴지지 않는지 확인한다.
- Stage 1 중반 이후 체력이 즉시 100%로 복구되는 빈도가 줄었는지 확인한다.
- 엘리트/보스 처치 후 캐시 획득 문구가 보상처럼 느껴지는지 확인한다.
- 격납고에서 캐시 stack UI가 충분히 명확한지 확인한다.
- GOOD 이상 캐시 개봉 시 “뭐가 나올까” 하는 기대감이 생기는지 확인한다.
- 캐시 개봉 후 모듈이 `Module [[Storage|Storage]]`에 자연스럽게 추가되는지 확인한다.
@@ -1,133 +0,0 @@
# Skybound Invasion Response Stage Difficulty Curve
작성일: 2026-04-26 13:08 KST
## 요청 요약
- Stage 8 보스가 지구를 침략한 핵심 적이라는 스토리 구조를 난이도 곡선에 반영한다.
- 초반에는 플레이어를 얕보고 소수의 적기만 보내는 느낌으로 시작한다.
- 스테이지를 클리어할수록 보스가 플레이어를 점점 더 위험하게 판단하고, 단계적으로 더 많은 적기를 투입한다.
- 적기의 수가 줄어든 구간은 너무 쉬워질 수 있으므로 적기의 공격력을 비례해서 보정한다.
## 핵심 방향
이번 패스는 단순히 숫자를 올리는 밸런스가 아니라 “침공군의 대응 수위”를 만드는 작업이다.
설계 기준은 다음과 같다.
1. Stage 1: 정찰대. 적 수는 적지만 한 발은 무시할 수 없다.
2. Stage 2: 빠른 대응기 투입. 아직 소규모지만 반응 속도가 오른다.
3. Stage 3: 혼합 편대. 보스가 플레이어를 실제 변수로 인식한다.
4. Stage 4: 제압 작전. 십자/라인 압박이 본격화된다.
5. Stage 5: 전면 공격 승인. 적 수가 확실히 늘어난다.
6. Stage 6: 제거 함대. 빌드 완성도를 검증한다.
7. Stage 7: 예비 전력 투입. 물량과 엘리트 압박이 커진다.
8. Stage 8: 지구 침공 본대. 최대 물량과 최대 화력으로 압박한다.
## 적용한 변경
### Stage Profile 재정렬
`SURVIVOR_STAGE_PROFILES`를 8단계 침공 대응 곡선으로 재배치했다.
변경된 주요 축:
- `diffBase`
- `capBase`
- `spawnTempo`
- opening wave density
- swarm density
- climax elite density
- comms 문구
### 초반 적 수 감소
Stage 1과 Stage 2는 보스가 플레이어를 얕보는 단계로 설정했다.
Stage 1 변경:
- `capBase: 18``12`
- `spawnTempo: 1.0``1.18`
- opening density: `8``4`
- swarm density: `18``12`
- climax elite density: `3``2`
Stage 2 변경:
- `capBase: 28``16`
- `spawnTempo: 0.86``1.02`
- opening density: `14``7`
- swarm density: `24``16`
- climax elite density: `4``3`
초반에는 화면을 적으로 가득 채우기보다, 각 적기의 진입과 탄환을 플레이어가 인식할 수 있게 만들었다.
### 중후반 적 수 증가 곡선 강화
Stage 5부터는 침공군이 실제로 플레이어 제거를 목표로 움직이는 느낌을 강화했다.
후반 주요 변화:
- Stage 5 `capBase: 40``34`, 대신 `diffBase: 1.42``1.54`
- Stage 6 `capBase: 46``42`, `diffBase: 1.58``1.74`
- Stage 7 `capBase: 52``50`, `diffBase: 1.76``1.96`
- Stage 8 `capBase: 58``60`, `diffBase: 1.96``2.22`
- Stage 8 swarm density: `60``68`
- Stage 8 climax elite density: `10``12`
Stage 5-7은 성능과 가독성을 고려해 단순 물량만 폭증시키지 않고, 공격 위협을 함께 올렸다.
### 공격력 보정
적 수가 줄어든 스테이지가 너무 쉬워지는 것을 방지하기 위해 `DAMAGE_CURVE`를 상향했다.
변경 전:
- `[0.95, 1.08, 1.24, 1.44, 1.68, 1.96, 2.28, 2.65]`
변경 후:
- `[1.08, 1.16, 1.32, 1.52, 1.78, 2.08, 2.44, 2.88]`
의도는 “적 수가 적으면 회피 기회가 많아지는 만큼, 맞았을 때는 실수로 느껴지게 하는 것”이다.
### Comms 서사 반영
스테이지 시작/주요 웨이브 문구를 침공 대응 서사에 맞게 수정했다.
예시:
- Stage 1: `Scout flight detected. The invader is probing our response.`
- Stage 2: `Stage 2: the invader is [[Testing|Testing]] faster response craft.`
- Stage 4: `Stage 4: the invader is no longer probing. Suppression grid active.`
- Stage 8: `Stage 8: planetary invasion force confirmed. Survive the crush.`
## 설계 의도
이번 변경의 핵심은 플레이어가 난이도 상승을 “게임이 갑자기 어려워졌다”가 아니라 “보스가 나를 점점 더 심각한 위협으로 보고 있다”라고 받아들이게 만드는 것이다.
초반은 적 수가 줄어들었기 때문에 회피와 학습의 여유가 있다.
하지만 공격력은 낮추지 않고 오히려 보정했기 때문에, 가만히 있어도 쉽게 깨지는 구조는 피한다.
후반은 플레이어 빌드가 강해지는 것을 전제로, 적 수와 공격력이 함께 올라간다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/CombatTimeline.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/balance.ts`
## 검증
- `npm run build` 성공
- `/sprites/player.png` 경고 없음
- 출력 디렉터리: `dist/25`
## 후속 플레이테스트 체크 포인트
- Stage 1 초반이 “적이 적어서 심심한지” 또는 “소수지만 긴장감이 있는지” 확인한다.
- Stage 1에서 맞았을 때 피격이 의미 있게 느껴지는지 확인한다.
- Stage 2가 Stage 1보다 확실히 대응 수위가 올라간 것처럼 느껴지는지 확인한다.
- Stage 3-4에서 혼합 편대/제압 작전으로 플레이 양상이 달라지는지 확인한다.
- Stage 5 이후부터 물량 증가가 명확하게 느껴지는지 확인한다.
- Stage 8이 최종 침공군답게 가장 강한 물량과 화력을 보여주는지 확인한다.
@@ -1,111 +0,0 @@
# Skybound Low Level First Upgrade Offer Balance
작성일: 2026-04-26 13:16 KST
## 요청 요약
- 게임 플레이 중 Tactical Level Up으로 무기/스킬 업그레이드 후보가 나온다.
- 이미 많이 레벨업한 무기가 계속 후보에 자주 나오면 특정 무기 몰빵이 쉬워진다.
- 레벨이 낮은 무기/스킬이 다음 후보에 포함될 확률을 더 높인다.
- 레벨이 높은 무기/스킬은 낮은 레벨 스킬 대비 후보 포함 확률을 낮춘다.
## 핵심 문제
기존 `ProgressionSystem.generateSkillCards()`는 이미 보유한 스킬과 near-max 스킬에 보너스를 주는 구조였다.
기존 구조의 문제:
1. 한 무기가 빠르게 고레벨까지 몰릴 수 있다.
2. Lv4 → Lv5 직전 스킬이 자주 후보에 떠서 성장 속도가 급격해진다.
3. 다양한 무기를 경험하기보다 가장 강한 무기 하나가 빠르게 완성된다.
4. Stage 1-2 중반부터 빌드가 너무 빨리 안정화될 수 있다.
## 적용한 변경
### 후보 선택 방식 변경
기존에는 카테고리별로 후보를 고르고, 보유/시너지/near-max에 가중치를 더했다.
변경 후에는 각 스킬마다 `offer weight`를 계산한다.
가중치 기준:
- 남은 레벨이 많을수록 가중치 증가
- Lv0/Lv1 스킬은 상대적으로 더 자주 등장
- Lv3 이상 스킬은 가중치 감소
- max 직전 스킬은 강하게 가중치 감소
- 시너지/EVO 보너스는 유지하되, 고레벨 스킬을 압도적으로 밀어주지는 않음
### 고레벨 몰빵 완화
Near-max 스킬은 기존에 오히려 보너스를 받았지만, 이제는 낮은 확률로만 나온다.
적용 규칙:
- `currentLevel >= maxLevel - 1`: 가중치 35%로 감소
- `currentLevel >= maxLevel * 0.6`: 가중치 58%로 감소
예시:
- Lv0/Lv1 스킬: 목록에 더 잘 등장
- Lv3/Lv4 스킬: 등장 가능하지만 낮은 빈도
- Lv4 → Lv5 완성: 운이 좋아야 뜨는 마무리 선택으로 변경
### 첫 선택 보정
아직 아무 스킬도 없는 첫 Tactical Level Up에서는 새 무기 후보를 우선 제공한다.
목표는 첫 선택이 빌드 방향을 정하는 순간으로 작동하게 하는 것이다.
### 새 무기 확장 선택 유지
이미 스킬을 보유한 이후에도 새 무기 후보가 완전히 사라지지는 않는다.
변경 후:
- 슬롯 여유가 있고 새 무기가 있으면 65% 확률로 하나의 build-expanding option을 제공한다.
- 나머지 후보는 전체 가중치 풀에서 선택한다.
### Mini-boss Reward Cache 보정
미니보스 보상 카드도 가장 높은 레벨 무기를 무조건 우선하지 않도록 변경했다.
변경 후에는 보유 무기 중에서도 낮은 레벨/남은 성장 여지가 큰 무기가 더 잘 선택된다.
### UI fallback 보정
일반적으로 카드 후보는 엔진에서 생성되지만, 예외적으로 `LevelUpModal`에서 fallback 랜덤이 동작할 수 있다.
이 fallback도 동일한 low-level-first 가중치 규칙을 따르도록 변경했다.
## 설계 의도
이번 변경의 목표는 성장 속도를 늦추는 것만이 아니다.
플레이어가 한 무기를 빠르게 완성해 “이미 빌드가 끝났다”라고 느끼는 시점을 뒤로 미루고, 여러 선택지 사이에서 더 오래 고민하게 만드는 것이 핵심이다.
원하는 플레이 감각:
1. 초반에는 새 무기와 낮은 레벨 무기가 자주 보인다.
2. 중반에는 빌드 방향을 넓히거나 약한 축을 보완하게 된다.
3. 고레벨 완성 선택은 자주 뜨지 않지만, 떴을 때 반갑다.
4. 특정 무기 하나가 너무 빨리 완성되어 난이도를 붕괴시키는 일이 줄어든다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/LevelUpModal.tsx`
## 검증
- `npm run build` 성공
- `/sprites/player.png` 경고 없음
- 출력 디렉터리: `dist/26`
## 후속 플레이테스트 체크 포인트
- Stage 1에서 같은 무기가 너무 빠르게 Lv4/Lv5까지 올라가지 않는지 확인한다.
- 낮은 레벨 무기/패시브가 기존보다 자주 후보에 뜨는지 확인한다.
- 고레벨 완성 선택이 너무 안 떠서 답답하지 않은지 확인한다.
- EVO 경로가 완전히 막힌 느낌이 들지 않는지 확인한다.
- 미니보스 보상 카드가 여전히 보상답게 느껴지는지 확인한다.
@@ -1,109 +0,0 @@
# Skybound Miniboss Treasure Cache Reward Loop
작성일: 2026-04-26 09:32 KST
## 요청 요약
- 뱀파이어 서바이벌 계열의 재미를 더 강하게 만들기 위한 다음 단계로, 미니보스 처치 보상 루프를 추가한다.
- 단순 EXP 성장만 반복되는 구조가 아니라, 중간 강적을 잡았을 때 빌드 방향을 강화하는 확정 보상을 제공한다.
- 보상은 기존 Tac Level Up 화면을 재사용하되, 보물상자 성격의 `Emergency Supply` 카드 선택으로 연결한다.
## 핵심 방향
Skybound의 현재 전투 루프는 적을 처치하면 Tac EXP를 바로 얻고, 일정 EXP에 도달하면 업그레이드를 선택하는 구조다. 이 방식은 화면 가독성에는 좋지만, 플레이 중간에 “강적을 잡아서 특별한 보상을 얻었다”는 뱀서류 특유의 보상감이 부족했다.
이번 변경의 목표는 미니보스를 다음 역할로 재정의하는 것이다.
1. 전투 흐름 중간의 압박 체크포인트
2. 플레이어 빌드가 충분히 강한지 확인하는 작은 검증 구간
3. 처치하면 현재 빌드를 더 선명하게 만드는 확정 업그레이드 보상
4. 보스 전 진화/EVO 경로를 완성할 기회를 주는 중간 보물상자
## 적용한 변경
### 미니보스 식별 플래그 추가
기존 `MINI_BOSS` 스폰은 내부적으로 `ELITE` 적을 생성했기 때문에, 처치 시 일반 엘리트와 구분되는 보상 처리가 어려웠다. `SystemEnemy`에 아래 플래그를 추가했다.
- `isMiniBoss`
- `rewardClaimed`
`SpawnerSystem``MINI_BOSS` 스폰에서는 이제 `isMiniBoss: true`를 부여한다.
### 미니보스 HP 스케일링
미니보스가 후반 스테이지에서도 너무 빨리 녹지 않도록 스테이지와 난이도 배율을 반영했다.
- 기본 HP: `620`
- 스테이지당 증가: `+22%`
- 현재 `difficultyMult` 반영
의도는 미니보스가 보스만큼 길지는 않지만, 플레이어가 위치와 공격 방향을 신경 써야 하는 짧은 전투 목표가 되게 하는 것이다.
### 처치 보상 인텐트 추가
`EngineProtocol``MINIBOSS_REWARD` 인텐트를 추가했다. `CombatSystem`은 미니보스 처치 시 직접 UI를 열지 않고, 엔진 인텐트를 통해 보상 처리를 요청한다.
이렇게 한 이유는 다음과 같다.
- 전투 시스템이 UI 상태를 직접 제어하지 않게 한다.
- 기존 `LEVEL_UP` 이벤트와 `LevelUpModal` 흐름을 재사용한다.
- 추후 보물상자 연출, 룰렛, 보상 티어를 추가하기 쉽다.
### 빌드 우선 보상 카드 생성
`ProgressionSystem``generateMiniBossRewardCards`를 추가했다. 이 보상은 일반 레벨업 카드보다 더 전략적으로 구성된다.
우선순위는 다음과 같다.
1. 이미 보유한 무기/스킬의 레벨업
2. Lv.3 이상 무기의 EVO에 필요한 서포트 패시브
3. 스웜/압박 구간 대응용 `isSpikeCounter` 스킬
4. 부족한 자리는 기존 3카드 생성 규칙으로 보충
이 구조는 플레이어가 아무 카드나 고르는 것이 아니라, “내 빌드를 완성해가는 선택”을 하도록 유도한다.
### 보상 UI 연결
미니보스 처치 시 아래 흐름으로 동작한다.
1. 미니보스 사망
2. `CombatSystem``MINIBOSS_REWARD` 인텐트 발행
3. `useGameEngine`이 현재 스킬 상태를 기반으로 보상 카드 생성
4. 게임 일시정지
5. `LEVEL_UP` 이벤트를 `isChest: true`로 발행
6. 기존 `Emergency Supply` 카드 선택 UI 표시
7. `COMMAND CACHE UNLOCKED` 피드백 텍스트 출력
## 설계 의도
이 변경은 Skybound의 목적성을 더 명확하게 만들기 위한 작업이다.
- 일반 적 처치: Tac EXP를 쌓는 기본 성장
- 엘리트 처치: 더 많은 EXP와 재료/장비 가능성
- 미니보스 처치: 확정 빌드 강화 선택
- 스테이지 보스 처치: 다음 스테이지 진행과 영구 보상
즉, 전투 중 목표가 “그냥 버티기”에서 “위험한 타이밍을 넘기고 빌드를 완성하기”로 바뀐다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/hooks/useGameEngine.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/EngineProtocol.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/SpawnerSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
## 검증
- `npm run build` 성공
- Vite 경고: `/sprites/player.png [[Reference|Reference]]d in /sprites/player.png didn't resolve at build time`
- 위 경고는 기존 런타임 경로 경고이며 이번 변경으로 인한 빌드 실패는 아니다.
## 후속 작업 제안
- 미니보스 처치 순간에 실제 상자/코어가 열리는 0.6초 전용 연출을 추가한다.
- 보상 카드에 `EVO READY`, `BUILD CORE`, `SURVIVAL PICK` 같은 태그를 붙여 선택 이유를 더 명확하게 보여준다.
- 스테이지별 미니보스 외형과 탄막 패턴을 분리해 “이번 스테이지의 중간 위협” 정체성을 강화한다.
- 보물상자 보상을 1장 선택에서 3장 순차 오픈 또는 희귀도 보상으로 확장할지 플레이테스트 후 결정한다.
@@ -1,63 +0,0 @@
# Skybound Player Sprite Path Warning Fix
작성일: 2026-04-26 12:11 KST
## 요청 요약
- `npm run build` 시 반복되던 `/sprites/player.png [[Reference|Reference]]d in /sprites/player.png didn't resolve at build time` 경고를 해결한다.
- 필요하다면 Skybound의 Stylized Casual Magitech 톤앤매너에 맞는 플레이어 기체 이미지를 새로 준비한다.
## 원인
경고의 원인은 실제 플레이 중 사용되는 Canvas 렌더링이 아니라, 선택 화면 CSS에서 존재하지 않는 `/sprites/player.png`를 참조하고 있었기 때문이다.
문제 위치는 `src/App.css`의 아래 클래스였다.
- `.plane-preview.falcon`
- `.plane-preview.rayce`
현재 프로젝트에는 `/sprites/player.png`가 없고, 실제 준비된 기체 에셋은 아래 파일이다.
- `/sprites/Falcon.png`
- `/sprites/rayce.png`
따라서 새 이미지를 생성하기보다, 이미 톤앤매너에 맞춰 준비된 실제 기체 에셋으로 경로를 정리하는 것이 적절했다.
## 적용한 변경
### Falcon 미리보기 경로 수정
`/sprites/player.png``/sprites/Falcon.png`로 교체했다.
### Rayce 미리보기 경로 수정
Rayce도 같은 `player.png``hue-rotate`를 걸어 임시로 표현하고 있었기 때문에, 실제 `/sprites/rayce.png`를 직접 사용하도록 바꿨다.
또한 임시 색상 변환 필터를 제거했다.
## 설계 의도
선택 화면은 사용자가 처음 기체의 정체성을 보는 곳이기 때문에, 존재하지 않는 공용 `player.png`나 임시 색상 변환보다 실제 기체별 에셋을 보여주는 편이 상품성 측면에서 낫다.
이번 수정으로 다음 효과가 있다.
- Vite 빌드 경고 제거
- Falcon/Rayce 선택 화면 미리보기 정확도 개선
- 임시 에셋 참조 제거
- 기존 Stylized Casual Magitech 기체 에셋 재사용
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/App.css`
## 검증
- `npm run build` 성공
- 기존 `/sprites/player.png` Vite 경고 사라짐
- 출력 디렉터리: `dist/21`
## 후속 작업 제안
- 선택 화면의 기체 미리보기를 정적 배경 이미지가 아니라, Canvas 렌더러와 동일한 축소 프리뷰 컴포넌트로 통일한다.
- Falcon/Rayce의 실제 플레이 성능 차이가 UI 문구와 정확히 대응되는지 점검한다.
- 선택 화면도 현재 게임 HUD/UI 톤과 완전히 맞도록 한 번 더 정리한다.
@@ -1,104 +0,0 @@
# Skybound Reward Card Clarity and Command Cache UI
작성일: 2026-04-26 09:40 KST
## 요청 요약
- 미니보스 보상 루프 다음 단계로, 보상 카드가 왜 좋은 선택인지 사용자가 즉시 이해할 수 있게 개선한다.
- 미니보스 처치 보상과 위기 보급 보상을 같은 화면처럼 보이지 않게 구분한다.
- Stylized Casual Magitech 톤앤매너 안에서 보상감 있는 카드 선택 UI를 강화한다.
## 핵심 방향
이전 단계에서 미니보스 처치 시 확정 업그레이드 선택 보상이 추가되었다. 하지만 카드 3장이 뜨는 것만으로는 사용자가 “왜 이 보상이 지금 내 빌드에 좋은지” 바로 이해하기 어렵다.
이번 변경의 목표는 보상 화면을 단순 선택지가 아니라, 플레이어에게 다음 메시지를 전달하는 UI로 만드는 것이다.
1. 이 카드는 현재 주력 빌드를 강화한다.
2. 이 카드는 EVO 진화 경로에 필요하다.
3. 이 카드는 스웜/압박 상황에서 생존에 도움이 된다.
4. 이 카드는 새로운 공격 패턴을 열어준다.
## 적용한 변경
### 보상 출처 타입 추가
`LEVEL_UP` 이벤트에 `rewardSource`를 추가했다.
- `STARTER`
- `LEVEL_UP`
- `POWER_SPIKE`
- `MINIBOSS`
기존에는 `isChest`만 있어서 미니보스 보상과 위기 보급 보상이 모두 같은 `Emergency Supply`처럼 보였다. 이제 보상 출처에 따라 헤더, 문구, 카드 태그를 다르게 표시할 수 있다.
### 미니보스 보상 헤더 차별화
미니보스 보상은 이제 `Emergency Supply`가 아니라 `Command Cache`로 표시된다.
- Badge: `Cache`
- Title: `Command Cache`
- Subtitle: `Choose one build-defining reward`
위기 보급은 기존 의도대로 `Emergency Supply`를 유지한다.
### 카드 선택 이유 태그 추가
각 카드 상단에 보상 이유 태그를 추가했다.
- `FIRST CORE`: 첫 무기 선택, 런의 시작 방향 결정
- `CORE UPGRADE`: 현재 주력 무기 강화
- `MODULE BOOST`: 보유 패시브/모듈 강화
- `EVO LINK`: 현재 무기의 진화 조건을 지원
- `EVO READY`: 진화 조건 완성
- `SURVIVAL PICK`: 스웜/압박 구간 대응
- `NEW WEAPON`: 새로운 공격 패턴 개방
- `UTILITY MOD`: 기본 성능 강화
이 태그는 단순 라벨이 아니라, 카드가 “왜 지금 의미 있는 선택인지”를 설명하는 짧은 문장과 함께 표시된다.
### Command Cache 연출 추가
보상 화면 상단에 작은 마법공학 캐시 코어를 추가했다.
- 팝 인 애니메이션
- 회전하는 점선 링
- 미니보스 캐시는 청록/라임 계열 빛
- 일반 보급은 오렌지/시안 계열 빛
실제 게임 시간을 더 지연시키지는 않지만, 화면이 뜨는 순간 보상 상자가 열린다는 감각을 강화한다.
## 설계 의도
뱀파이어 서바이벌 계열의 재미는 단순히 레벨업을 많이 하는 것이 아니라, “내가 고른 선택 때문에 빌드가 강해지고 있다”는 확신에서 나온다.
이번 변경은 그 확신을 UI로 보강한다.
- 미니보스 처치: `Command Cache`
- 위기 보급: `Emergency Supply`
- 일반 레벨업: `Tactical Upgrade`
- 시작 선택: `Choose First Weapon`
이제 각 성장 이벤트는 같은 카드 선택이라도 서로 다른 의미를 가진다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/hooks/useGameEngine.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/GameSceneRenderer.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/LevelUpModal.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/LevelUpModal.css`
## 검증
- `npm run build` 성공
- Vite 경고: `/sprites/player.png [[Reference|Reference]]d in /sprites/player.png didn't resolve at build time`
- 위 경고는 기존 런타임 경로 경고이며 이번 변경으로 인한 빌드 실패는 아니다.
## 후속 작업 제안
- 스테이지별 미니보스 패턴을 분리해 `Command Cache`를 얻는 과정 자체를 더 재미있게 만든다.
- 보상 카드에 실제 EVO 결과 미리보기 아이콘을 추가한다.
- 보물상자 보상을 1장 선택에서 희귀도 기반 다중 보상으로 확장할지 플레이테스트한다.
- Command Cache가 열리는 짧은 0.5초 전용 컷인/상자 오픈 애니메이션을 Canvas 위에 추가한다.
@@ -1,136 +0,0 @@
# Skybound Skill Slot Limit Weapon 5 Passive 5
작성일: 2026-04-26 13:29 KST
## 요청 요약
- 사용자가 획득할 수 있는 스킬 수량에 제한을 둔다.
- 총 10개 스킬을 보유할 수 있게 한다.
- 10개 중 5개는 무기, 5개는 패시브로 분리한다.
- 슬롯이 부족한 상태에서 새 스킬을 선택하려 하면 `슬롯이 부족합니다`에 해당하는 노티가 필요하다.
- 슬롯 제한 때문에 사용하지 못하는 스킬이 목록에 나올 수 있으므로 `Skip Upgrade` 선택지도 계속 필요하다.
- 5/5 구조가 적절한지 검토한다.
## 판단
현재 Skybound에는 무기와 패시브 풀이 이미 넓고, 8스테이지까지 성장해야 한다.
따라서 지금 시점에서는 `무기 5개 + 패시브 5개`가 적절하다.
더 줄이는 선택지도 가능하지만, 아직은 권장하지 않는다.
- 4/4는 빌드 정체성이 더 강해지는 대신 초반 선택 운 영향이 커진다.
- 5/5는 Survivor.io/Vampire Survivors류의 성장 폭과 전략성을 적당히 유지한다.
- 6/6 이상은 사용자가 거의 모든 것을 들고 가는 느낌이 강해져 빌드 선택 의미가 약해진다.
그래서 이번 패스에서는 5/5를 기본값으로 적용했다.
## 적용한 변경
### Skill Slot Limit 추가
`skills.ts`에 슬롯 제한 상수를 추가했다.
```ts
export const SKILL_SLOT_LIMITS = {
WEAPON: 5,
PASSIVE: 5,
}
```
이제 시스템 전반에서 동일한 기준을 사용한다.
### 후보 생성 필터링
`ProgressionSystem.generateSkillCards()``generateMiniBossRewardCards()`에서 슬롯 제한을 반영했다.
규칙:
- 이미 보유한 스킬은 계속 레벨업 가능하다.
- 새 무기 획득은 무기 슬롯이 5개 미만일 때만 가능하다.
- 새 패시브 획득은 패시브 슬롯이 5개 미만일 때만 가능하다.
- 슬롯이 꽉 찬 타입의 새 스킬은 정상 후보 생성에서 제외한다.
### 선택 시 슬롯 부족 방어
혹시 예외 경로로 선택 불가 카드가 들어오거나, UI/엔진 동기화 타이밍 문제로 새 스킬 선택이 들어올 수 있다.
그래서 `ProgressionSystem.applySkillSelection()`에도 최종 방어를 추가했다.
슬롯이 부족하면:
- 스킬을 추가하지 않는다.
- 게임을 재개한다.
- 전투 화면에 `WEAPON SLOTS FULL` 또는 `PASSIVE SLOTS FULL` 텍스트를 띄운다.
- 보조 텍스트로 `Choose another module or skip`을 띄운다.
### Store 레벨 방어
`useGameStore.addSkill()`에도 동일한 슬롯 제한 방어를 추가했다.
이유:
- UI나 엔진 외부에서 `addSkill()`이 호출되더라도 잘못된 스킬이 저장되지 않게 하기 위함이다.
- `__skip__`도 기존처럼 저장되지 않는다.
### Level Up UI 슬롯 상태 표시
`LevelUpModal` 상단에 현재 슬롯 상태를 표시한다.
표시:
- `Weapons 0/5`
- `Passives 0/5`
슬롯이 가득 차면 해당 배지가 붉은 톤으로 바뀐다.
### SLOT FULL 카드 표시
정상 후보 생성에서는 사용 불가 카드가 거의 나오지 않지만, 예외적으로 pre-generated cards나 fallback 상태에서 들어올 수 있다.
이 경우 카드에 다음 표시를 추가했다.
- `SLOT FULL` 태그
- `No empty weapon/passive slot` 설명
- `WEAPON slots are full` 또는 `PASSIVE slots are full`
사용자는 이때 새로 추가된 `Skip Upgrade`를 선택해 넘길 수 있다.
## 설계 의도
슬롯 제한의 핵심은 빌드 선택을 더 전략적으로 만드는 것이다.
제한이 없으면 사용자는 결국 대부분의 무기와 패시브를 다 들고 가게 되고, 선택의 의미가 약해진다.
5/5 구조에서는 다음 판단이 생긴다.
1. 무기 슬롯 하나를 새 무기에 쓸 것인가?
2. 기존 무기 레벨업을 기다릴 것인가?
3. 패시브 슬롯을 EVO 재료에 쓸 것인가?
4. 생존 패시브를 포기하고 공격 패시브를 가져갈 것인가?
5. 지금 후보가 별로면 스킵할 것인가?
이번 변경은 `Skip Upgrade`의 존재 이유도 더 명확하게 만든다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/skills.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/store/useGameStore.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/LevelUpModal.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/LevelUpModal.css`
## 검증
- `npm run build` 성공
- `/sprites/player.png` 경고 없음
- 출력 디렉터리: `dist/28`
## 후속 플레이테스트 체크 포인트
- 무기 5개를 보유한 상태에서 새 무기 후보가 정상 레벨업 목록에서 제외되는지 확인한다.
- 패시브 5개를 보유한 상태에서 새 패시브 후보가 정상 레벨업 목록에서 제외되는지 확인한다.
- 이미 보유한 무기/패시브는 슬롯이 가득 차도 레벨업 가능한지 확인한다.
- 예외적으로 `SLOT FULL` 카드가 보일 때 선택하면 슬롯 부족 노티가 뜨는지 확인한다.
- `Skip Upgrade`가 슬롯 제한 상황에서 자연스러운 탈출구로 작동하는지 확인한다.
- 5/5가 너무 넉넉하거나 너무 답답하지 않은지 확인한다.
@@ -1,150 +0,0 @@
# Skybound Skip Upgrade and Weapon Transform Reconfiguration
작성일: 2026-04-26 13:25 KST
## 요청 요약
- Tactical Level Up 화면에서 마음에 들지 않는 업그레이드만 나올 수 있다.
- 이 경우 사용자가 강제로 원하지 않는 업그레이드를 고르지 않도록 `업글 안하기` 선택지를 추가한다.
- 새로운 무기가 장착되었을 때 사용자의 기체 외형도 그에 맞춰 변화해야 한다.
- 연출적으로는 트랜스포머처럼 기체가 재구성되고 무장이 전개되는 느낌을 표현한다.
## 핵심 문제
기존 레벨업 화면은 반드시 하나의 스킬을 선택해야 했다.
이 구조의 문제:
1. 현재 빌드와 맞지 않는 선택지만 나와도 강제로 선택해야 한다.
2. 낮은 레벨 우선 후보 확률을 적용한 뒤에는 사용자가 원치 않는 저레벨/새 무기가 뜰 가능성도 생긴다.
3. 새 무기를 획득해도 기체가 실제로 바뀌는 느낌이 약하다.
4. 무기가 생긴 순간의 시각적 보상이 부족하다.
## 적용한 변경
### Skip Upgrade 선택지 추가
`LevelUpModal``Skip Upgrade` 카드를 추가했다.
동작:
- STARTER 첫 무기 선택에서는 스킵이 나오지 않는다.
- 일반 Tactical Upgrade, Supply, Command Cache에서는 스킵 가능하다.
- 스킵을 선택하면 스킬/무기 레벨이 증가하지 않고 전투로 복귀한다.
표시 문구:
- `HOLD UPGRADE`
- `Skip Upgrade`
- `No change this time`
### Skip 안전 처리
`__skip__`이 실제 스킬처럼 저장되지 않도록 여러 지점에 방어를 추가했다.
적용 지점:
- `GameSceneRenderer`
- `ProgressionSystem`
- `useGameStore.addSkill`
`__skip__`이 선택되면:
- Zustand `skills`에 추가하지 않는다.
- 엔진 스킬 상태에도 추가하지 않는다.
- `TACTICAL UPGRADE HELD` 텍스트를 띄운다.
- 게임 pause를 해제하고 전투를 재개한다.
### 새 무기 장착 감지
`ProgressionSystem.applySkillSelection()`에서 선택 직전 스킬 레벨을 확인한다.
조건:
- 선택한 스킬이 `WEAPON` 타입
- 선택 직전 레벨이 0
이 조건을 만족할 때만 새 무기 장착 연출을 발동한다.
기존 무기 레벨업이나 패시브 선택은 변신 연출을 발동하지 않는다.
### Airframe Reconfiguration 상태 추가
`Game[[State|State]]`에 새 무기 장착 연출용 상태를 추가했다.
추가 필드:
- `weaponTransformStartFrame`
- `weaponTransformDuration`
- `weaponTransformSkillId`
이 값은 렌더러가 현재 프레임 기준으로 변신 진행도를 계산하는 데 사용한다.
### 기체 변신/무장 전개 연출 추가
`GameRenderer.renderPlayer()`에 새 무기 장착 연출을 추가했다.
연출 요소:
- 기체 중심에서 확장되는 아케인 스캔 링
- 무기 색상별 발광
- 좌우 장갑 패널이 바깥으로 접히듯 전개
- 전방 무장 레일이 앞으로 돌출
- 작은 locking spark
- `WEAPON LINK: 무기명`
- `AIRFRAME RECONFIGURING`
- 화면 흔들림과 파티클
무기별 액센트 컬러:
- Gatling Gun: 골드
- Missile Pod: 핑크/레드
- Nova Burst: 시안
- Energy Shield: 라임
- Sweep Laser: 화이트/시안
- Plasma Torpedo: 오렌지
- Ion Storm: 전기 시안
- Attack Drone: 라임
- Gravity Mine: 퍼플
- Plasma Fire: 오렌지/레드
- Plasma Blade: 시안
## 설계 의도
이번 변경은 업그레이드 UX에 “선택하지 않을 권리”를 추가하는 작업이다.
업그레이드는 항상 이득처럼 보여야 하지만, 빌드 방향과 맞지 않는 선택을 강제하면 사용자는 선택권을 잃었다고 느낄 수 있다.
스킵 선택지는 다음 의미를 가진다.
1. 원하지 않는 업그레이드를 강제로 먹지 않는다.
2. 빌드 순도를 유지할 수 있다.
3. 낮은 레벨 우선 후보 시스템의 부작용을 완화한다.
4. 선택 화면에서 사용자 판단 여지를 높인다.
새 무기 변신 연출은 “새 기능이 생겼다”를 UI 문구가 아니라 기체 자체 변화로 전달하기 위한 장치다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/store/useGameStore.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/GameRenderer.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/GameSceneRenderer.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/LevelUpModal.tsx`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/ui/LevelUpModal.css`
## 검증
- `npm run build` 성공
- `/sprites/player.png` 경고 없음
- 출력 디렉터리: `dist/27`
## 후속 플레이테스트 체크 포인트
- 일반 레벨업 화면에서 `Skip Upgrade`가 명확하게 보이는지 확인한다.
- STARTER 첫 무기 선택에서는 스킵이 나오지 않는지 확인한다.
- 스킵 선택 시 게임이 정상 재개되는지 확인한다.
- 스킵 선택 후 `skills.__skip__` 같은 잘못된 값이 저장되지 않는지 확인한다.
- 새 무기를 처음 선택했을 때 기체 변신 연출이 충분히 눈에 띄는지 확인한다.
- 기존 무기 레벨업/패시브 선택 시 변신 연출이 과하게 반복되지 않는지 확인한다.
@@ -1,205 +0,0 @@
# Skybound Stage 1 to 3 Playtest Balance Bomb and Visual Diversity Pass
작성일: 2026-04-26 12:35 KST
## 요청 요약
- Stage 1부터 Stage 3까지 실제 플레이 후 느낀 문제를 개선한다.
- Stage 1 초반 적 탄속이 부담스럽고, 중반 이후 성장하면 너무 쉬워지는 문제를 조정한다.
- Stage 2 시작 시 이미 Tac Level 6 정도로 강해져 적이 화면에 들어오기 전에 사망하는 문제를 완화한다.
- Space/X 폭탄의 비주얼 이펙트가 약하므로 톤앤매너에 맞는 폭탄 연출을 강화한다.
- 일반 적, 엘리트, 미니보스, 보스 외형 다양성을 확보한다.
## 핵심 문제
플레이 피드백 기준으로 Skybound의 현재 문제는 초반과 중반의 난이도 감각이 반대로 작동한다는 점이었다.
1. Stage 1 초반은 적 탄속이 빠르게 느껴져 부담스럽다.
2. Stage 1 중반부터 스킬이 붙으면 플레이어 화력이 너무 급격히 상승한다.
3. Stage 2에서는 적이 화면에 들어오기 전에 사망해 긴장감이 사라진다.
4. Tac Level 성장 속도와 무기 효율이 합쳐져 “이미 완성된 빌드”처럼 느껴진다.
5. 보스/적기 외형 반복으로 스테이지 진행감이 약하다.
## 적용한 변경
### Stage 1 적 탄속 완화
`balance.ts`의 적 탄환 기본 속도와 스테이지별 탄속 커브를 낮췄다.
변경 전:
- `BULLET_BASE_SPEED: 3.75`
- `BULLET_SPEED_CURVE: [1.1, 1.28, 1.48, ...]`
변경 후:
- `BULLET_BASE_SPEED: 3.25`
- `BULLET_SPEED_CURVE: [0.82, 0.96, 1.12, ...]`
Stage 1은 회피를 학습할 수 있는 속도로 낮추고, Stage 4 이후부터 탄속이 본격적으로 올라가도록 재배치했다.
### 적 사격 템포 완화
초반 탄막 부담을 줄이기 위해 `FIRE_RATE_CURVE`도 조정했다.
변경 후:
- `[280, 248, 222, 198, 176, 154, 134, 116]`
Stage 1-2는 더 읽을 수 있게 만들고, 후반 스테이지는 기존처럼 빠르게 압박하도록 유지했다.
### Tac Level 성장 속도 완화
Tac Level이 Stage 1 중반에 너무 빨리 누적되지 않도록 조정했다.
- 시작 요구 EXP: `80``100`
- 레벨업 후 초과 EXP carryover: `25%``15%`
- 레벨업 lockout: `360프레임``480프레임`
- 일반 적 Tac EXP: `2``1`
- 엘리트 Tac EXP: `10``8`
- 미니보스 Tac EXP: `30``24`
목표는 Stage 2 시작 시 플레이어가 강해졌다는 느낌은 가지되, 이미 완성된 상태는 아니게 만드는 것이다.
### 플레이어 무기 초중반 효율 완화
무기 업그레이드가 의미는 있지만, Lv1-3에서 화면 전체를 지우지 않도록 주요 피해량을 조정했다.
- Gatling Gun 피해와 발사 효율 하향
- Hyper Laser 피해 하향
- Nova Burst 피해 하향
- Missile Pod, Rocket Launcher, Ion Storm, Gravity Mine, Blade Orbit 등 데이터 기반 무기 피해 하향
- EVO 무기도 일부 피해를 낮춰 Stage 2-3을 통째로 삭제하지 않게 조정
### 화면 밖 적 선삭제 방지
Stage 2에서 적이 화면에 나오기도 전에 사망하는 가장 큰 원인은 자동 조준/유도/빔/드론/오비트 무기가 `y < 0`에 있는 적까지 타겟팅하거나 피해를 주는 것이었다.
그래서 플레이어 무기 타겟팅과 충돌 판정에 `TARGETABLE_Y = -35` 기준을 추가했다.
적이 화면에 거의 진입하기 전까지는 다음 무기가 타겟팅하지 않는다.
- 유도탄
- 자동 조준 무기
-
- 오비트 무기
- 드론
- 설치/장판 무기
- 일반 플레이어 탄환 충돌
이제 적이 화면에 들어와 위협을 보여준 뒤 처치되는 흐름이 만들어진다.
### Stage 2-3 압박 보강
Stage 2와 Stage 3은 이미 성장한 플레이어를 전제로 난이도를 다시 올렸다.
Stage 2:
- `diffBase: 1.02``1.12`
- `capBase: 23``28`
- `spawnTempo: 0.94``0.86`
- opening density: `10``14`
Stage 3:
- `diffBase: 1.14``1.28`
- `capBase: 28``34`
- `spawnTempo: 0.88``0.78`
- opening density: `12``16`
### 적 HP 스케일링 보강
일반/엘리트 적이 스킬 몇 개에 바로 삭제되지 않도록 기본 HP 공식을 조정했다.
추가 요소:
- 스테이지별 HP 증가
- 플레이어가 예상보다 높은 Tac Level일 때 적 HP 보정
- 엘리트 HP 배율 상향
이 보정은 플레이어가 잘 성장했을 때도 적이 최소한 화면에 들어와 압박을 만들도록 하기 위한 안전장치다.
### 폭탄 비주얼 개선
기존 폭탄은 얇은 원형 렌더링에 가까워 비주얼 피드백이 약했다. 이제 폭탄 사용 시 발동 위치를 저장하고, 그 지점에서 Magitech shockwave가 확장된다.
추가된 연출:
- 고정된 폭발 원점
- 시안/라임/골드 3중 마법공학 링
- 점선 링 회전
- 중심 코어 플래시
- 방사형 에너지 라인
- 밝은 라디얼 플래시
Space/X를 눌렀을 때 “화면을 정리하는 기술”이라는 감각이 더 강해지도록 했다.
### 적기 외형 다양성 개선
기존 적기 스프라이트 선택은 역할별 고정값이 많아 반복감이 컸다. 이제 역할과 스테이지, 약간의 랜덤 salt를 반영해 더 다양한 스프라이트를 선택한다.
적용 대상:
- 일반 적
- 엘리트 적
- 미니보스
미니보스는 패턴별로 크기와 발광색도 달라져 작은 보스전처럼 보이게 했다.
### 보스 외형 다양성 개선
보스는 `spriteIdx`가 명시되지 않아 사실상 같은 보스 타일만 반복 사용되는 문제가 있었다. 이제 스테이지별 보스 비주얼 프로필을 갖는다.
프로필 요소:
- 보스 스프라이트 인덱스
- 보스 크기
- 보스 가로/세로 비율
- 날개 포탑 위치
- 하단 포탑 위치
- 발광 액센트 색상
이제 Stage 1-8 보스는 같은 시스템을 쓰더라도 외형, 크기, 포탑 배치가 다르게 보인다.
## 설계 의도
이번 패스의 핵심은 “초반은 읽기 쉽게, 중반은 무적감이 너무 빨리 오지 않게” 만드는 것이다.
원하는 플레이 감각은 다음과 같다.
1. Stage 1 초반: 탄을 보고 피하는 법을 배운다.
2. Stage 1 중반: 첫 빌드가 강해지는 재미를 느낀다.
3. Stage 1 후반: 미니보스와 보스로 빌드 검증을 한다.
4. Stage 2: 성장한 상태지만 적도 더 빨리/많이 들어와 다시 긴장감이 생긴다.
5. Stage 3: 단일 무기 강화만으로는 부족하고 광역/방어/관통 선택의 의미가 생긴다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/CombatTimeline.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/balance.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/config/weapon[[Behavior|Behavior]]s.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/store/useGameStore.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/GameRenderer.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ModularWeaponSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/PlayerSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/ProgressionSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/SpawnerSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/StageDirectorSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/WeaponBehaviorEngine.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
## 검증
- `npm run build` 성공
- `/sprites/player.png` 경고 없음
- 출력 디렉터리: `dist/22`
## 후속 플레이테스트 체크 포인트
- Stage 1 첫 60초 탄속이 “부담스럽지만 불공정하지 않은지” 확인한다.
- Stage 1 후반 Tac Level이 대략 3-5 사이인지 확인한다.
- Stage 2 시작 시 적이 화면 안에 들어오기 전에 삭제되는 현상이 줄었는지 확인한다.
- Space/X 폭탄 사용 시 충분히 강한 시각 피드백이 있는지 확인한다.
- Stage 1-3 보스가 서로 다른 외형과 크기로 인식되는지 확인한다.
- Stage 2-3에서 피격 압박은 생겼지만, 갑자기 불합리하게 어려워지지는 않았는지 확인한다.
@@ -1,115 +0,0 @@
# Skybound Stage Miniboss Pattern Differentiation
작성일: 2026-04-26 09:44 KST
## 요청 요약
- 미니보스 보상 루프 다음 단계로, 8개 스테이지마다 미니보스 전투 패턴을 다르게 만든다.
- `Command Cache`를 얻는 과정 자체가 작은 보스전처럼 느껴지게 한다.
- 스테이지가 올라갈수록 압박 방식이 달라져 반복감을 줄이고, 플레이어가 이동/회피/빌드 선택을 더 의식하게 만든다.
## 핵심 방향
기존 미니보스는 내부적으로 `ELITE + COMMANDER`에 가까웠고, 일반 적 사격 규칙을 타고 있었다. 그래서 미니보스를 처치하면 보상은 의미 있어졌지만, 전투 자체는 “체력이 많은 엘리트”처럼 느껴질 위험이 있었다.
이번 변경은 미니보스를 아래 역할로 재정의한다.
1. 각 스테이지 중반의 작은 실력 체크
2. 스테이지 기믹을 미리 보여주는 압박 패턴
3. `Command Cache` 보상을 얻기 위한 전투 목표
4. 보스전 전 빌드가 충분한지 검증하는 중간 관문
## 적용한 변경
### 미니보스 패턴 타입 추가
`SystemEnemy`에 미니보스 전용 패턴 상태를 추가했다.
- `miniBossPattern`
- `miniBossTimer`
- `miniBossCooldown`
- `miniBossDashFrames`
- `miniBossAction[[Seed|Seed]]`
- `dashTargetX`
- `dashTargetY`
일반 적 AI에는 영향을 주지 않고, `isMiniBoss`가 true인 적만 전용 이동/사격 로직을 사용한다.
### 스테이지별 패턴 매핑
`SpawnerSystem`에서 현재 스테이지에 따라 미니보스 패턴을 자동 부여한다.
- Stage 1: `DUELIST`
- Stage 2: `DASH_RAIDER`
- Stage 3: `DRONE_CALLER`
- Stage 4: `BARRAGE_WALL`
- Stage 5: `MINE_LAYER`
- Stage 6: `DRONE_RING`
- Stage 7: `[[Blink|Blink]]_SNIPER`
- Stage 8: `OMEGA_COMMANDER`
### 전용 이동 AI 추가
`CombatSystem`에서 미니보스는 기존 `role` 기반 AI 대신 `updateMiniBossAI`를 탄다.
패턴별 이동/행동은 다음과 같다.
- `DUELIST`: 플레이어 x축을 따라가며 기본 팬샷 압박
- `DASH_RAIDER`: 짧은 예고 후 플레이어 방향으로 돌진
- `DRONE_CALLER`: 좌우에 스팅어 호위기를 주기적으로 소환
- `BARRAGE_WALL`: 화면 가로 라인을 오가며 안전 구멍이 있는 탄막벽 생성
- `MINE_LAYER`: 플레이어 근처에 위험 구름/지뢰형 압박 구역 생성
- `DRONE_RING`: 헌터 호위기와 링 탄막으로 공간 압박
- `BLINK_SNIPER`: 위치를 순간이동하며 빠른 저격 탄을 발사
- `OMEGA_COMMANDER`: 팬샷, 링 탄막, 지뢰, 블링크를 순환하는 최종형 미니보스
### 전용 사격 패턴 추가
`spawnMiniBossBulletPattern`을 추가해 미니보스 사격을 일반 적과 분리했다.
- 팬샷
- 빠른 저격탄
- 링 탄막
- 안전 구멍이 있는 라인 탄막
- 느린 중력/지뢰형 탄
- 최종 스테이지 혼합 패턴
스테이지가 올라가면 탄 수와 쿨다운이 자연스럽게 강해진다.
## 설계 의도
이번 변경은 “보상을 얻는 과정”을 재미있게 만들기 위한 작업이다.
이전 구조:
- 미니보스 등장
- 체력이 많은 적을 처치
- 보상 선택
변경 후 구조:
- 스테이지별 다른 압박을 가진 미니보스 등장
- 사용자는 이동/회피/빌드 강점을 이용해 작은 보스전을 해결
- 처치하면 `Command Cache`를 열고 빌드를 강화
- 다음 구간을 버틸 준비가 된다
이렇게 하면 미니보스가 단순 보상 트리거가 아니라, 스테이지 리듬의 핵심 이벤트가 된다.
## 수정 파일
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/CombatSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/SpawnerSystem.ts`
- `/Volumes/Data/project/Antigravity/Skybound/src/features/game/systems/types.ts`
## 검증
- `npm run build` 성공
- Vite 경고: `/sprites/player.png [[Reference|Reference]]d in /sprites/player.png didn't resolve at build time`
- 위 경고는 기존 런타임 경로 경고이며 이번 변경으로 인한 빌드 실패는 아니다.
## 후속 작업 제안
- 실제 플레이에서 Stage 4 `BARRAGE_WALL`과 Stage 7 `BLINK_SNIPER`의 탄속/쿨다운을 체감 기준으로 조정한다.
- 미니보스 등장 시 패턴 이름을 더 상품성 있는 경고 문구로 표시한다.
- 미니보스별 외형 색상, 엔진 이펙트, 코어 형태를 패턴에 맞게 분리한다.
- `Command Cache` 오픈 전 0.5초 컷인 연출을 추가해 전투 승리 보상감을 더 강화한다.
@@ -1,31 +0,0 @@
# [[Accessibility (A11y)|Accessibility (A11y]]
## 📌 Brief Summary
접근성([[Accessibility|Accessibility]], A11y)은 스크린 리더, 키보드 네비게이션 등을 지원하여 모든 사용자가 차별 없이 UI를 이용할 수 있도록 하는 설계 원칙 및 기능입니다 [1, 2]. React 컴포넌트 아키텍처와 디자인 시스템에서 재사용성은 접근성과 뗄 수 없는 관계를 가지며, ARIA 속성 및 시맨틱 HTML 적용을 기본으로 합니다 [3, 4]. 잘 설계된 컴포넌트 라이브러리와 아키텍처 패턴은 개발자가 처음부터 접근성을 구현할 필요 없이, 접근성 테마 모드나 포커스 관리 등과 같은 내장된 접근성 지원을 제공합니다 [1, 5, 6].
## 📖 Core Content
* **재사용 가능한 컴포넌트와 접근성 우선(Accessibility First) 원칙**
재사용 가능한 컴포넌트를 설계할 때 접근성은 선택 사항이 아니라 필수 사항입니다 [2]. 키보드 탭 순서 관리, 화살표 키 탐색, 올바른 시맨틱 HTML 역할(Roles)과 레이블, 포커스 제어 및 오류 메시지 제공 등은 컴포넌트의 핵심 기능에 내장(Bake into the DNA)되어야 합니다 [2, 6]. 컴포넌트가 진화하더라도 접근성 역할, 레이블, 포커스 상태가 깨지지 않는지 확인하기 위해 지속적인 접근성 검사(Accessibility checks)가 필요합니다 [7].
* **아키텍처 패턴을 통한 접근성 구현**
* **[[Compound Components|Compound Components]]:** 부모 컴포넌트(예: Accordion)가 자식 컴포넌트들의 상태를 제어하는 방식은 접근성 구현을 단순하게 만듭니다. 컨텍스트를 통해 내부 상태를 공유하기 때문에, 사용자가 명시적으로 ID를 전달하지 않아도 `aria-controls``aria-labelledby` 같은 속성을 자동으로 연결해 줄 수 있습니다 [8].
* **[[Headless Components|Headless Components]]:** 이 패턴은 상태 관리, 로직, 그리고 접근성 기능(키보드 네비게이션, ARIA 역할 등)을 내장하여 제공하되, 스타일링은 개발자가 [[Tailwind CSS|Tailwind CSS]] 등으로 자유롭게 구성하도록 맡기는 방식으로 현대적이고 접근성이 뛰어난 UI 구축에 활용됩니다 [9].
* **디자인 시스템 및 테마 기반 접근성**
디자인 토큰을 기반으로 한 테마 시스템은 접근성 요구 사항을 유연하게 수용할 수 있습니다 [5, 10]. 예를 들어, 디자인 테마는 다크 모드뿐만 아니라 모든 요소를 더 눈에 띄게 만드는 고대비(High-contrast) 테마나 제한된 움직임(Limited movement)과 같은 사용자 기본 설정에 맞춰 동적으로 조정될 수 있습니다 [5, 10, 11].
* **주요 라이브러리 및 도구의 접근성 지원의 차이**
* Shopify의 Polaris와 Uber의 Base Web과 같은 최신 라이브러리는 키보드 내비게이션, ARIA 역할, 스크린 리더 호환성 및 WCAG 표준 준수를 기본 기능으로 제공합니다 [1, 3, 12, 13].
* 반면 Tailwind CSS와 같은 유틸리티 우선 프레임워크는 스타일링에 특화되어 있어 자동으로 `aria-*` 속성이나 시맨틱 HTML 요소로 변경해주지 않습니다 [4]. 따라서 Tailwind CSS를 사용할 때는 개발자가 올바른 ARIA 속성과 시맨틱 마크업을 명시적으로 포함해야 합니다 [4].
* **대규모 접근성 문서화 및 관리 자동화**
Uber와 같은 대규모 환경에서는 VoiceOver, TalkBack, ARIA와 같은 3가지 접근성 API를 커버해야 하며, 각각 수백 개의 속성이 존재하기 때문에 수동으로 스펙을 관리하기 어렵습니다 [14]. 이를 해결하기 위해 AI 에이전트([[Figma|Figma]] Console MCP 활용)를 도입하여 컴포넌트 트리를 스크랩하고 다중 플랫폼의 스크린 리더 및 접근성 속성을 단 몇 분 만에 포괄적인 스펙 문서로 자동 렌더링하는 자동화 파이프라인을 구축하여 접근성 기준을 유지합니다 [15-18].
## 🔗 Knowledge Connections
- **Related Topics:** [[Compound Components|Compound Components]], Headless Components, Design Tokens, [[Tailwind CSS|Tailwind CSS]]
- **Projects/Contexts:** [[Uber Base Web|Uber Base Web]], Shopify Polaris, [[React Component Library Architecture|React Component Library Architecture]]
- **Contradictions/Notes:** 컴포넌트 레벨에서의 접근성 내장 여부에서 프레임워크 간 차이가 발생합니다. [[Shopify Polaris|Shopify Polaris]]나 [[Uber Base Web|Uber Base Web]] 등의 완전한 UI 컴포넌트 라이브러리는 ARIA 및 키보드 조작과 같은 접근성을 기본으로 제공하지만 [1, 3, 12], Tailwind CSS를 단독으로 사용할 경우 자동으로 접근성 태그를 부여하지 않으므로 개발자가 직접 시맨틱 마크업과 ARIA 속성을 챙겨야 한다는 명확한 한계(책임의 전가)를 지적하고 있습니다 [4].
---
*Last updated: 2026-04-26*
@@ -1,21 +0,0 @@
# [[Accessibility|Accessibility]]
## 📌 Brief Summary
접근성(Accessibility, A11y)은 장애 여부나 기기 환경에 관계없이 모든 사용자가 인터페이스를 원활하게 이용할 수 있도록 보장하는 핵심 설계 원칙이다 [1]. 확장 가능한 React 컴포넌트 아키텍처에서는 재사용성을 확보하기 위해 ARIA 역할(roles), 키보드 탐색, 포커스 관리, 화면 판독기(Screen-reader) 지원 등을 컴포넌트 단계에서 기본적으로 내장해야 한다 [1-3].
## 📖 Core Content
- **재사용 가능한 컴포넌트의 필수 조건**: 접근성은 디자인 완료 후 나중에 추가하는 것이 아니라 '최우선(First-Class)'으로 컴포넌트의 DNA에 내장되어야 한다 [1, 3]. 접근성을 나중에 덧붙이는 방식(afterthought)으로 처리하면 비용과 수고가 두 배로 든다 [4]. 상호작용 요소에는 적절한 시맨틱 태그, 역할(roles), 라벨, 포커스 관리 및 키보드 탐색(Tab, 화살표 키, Home/End 등) 기능이 필수적으로 포함되어야 한다 [1, 3, 5].
- **디자인 토큰과 시스템을 통한 접근성 향상**: 디자인 토큰 기반의 테마 시스템을 적용하면 고대비(high-contrast) 모드나 모션 감소(limited movement)와 같이 다양한 사용자 선호도 및 접근성 요구 사항에 맞춰 인터페이스를 쉽게 조정할 수 있다 [6].
- **스타일링 도구 및 아키텍처 패턴의 접근성 처리**:
- **[[Tailwind CSS|Tailwind CSS]]**: 유틸리티 클래스를 통한 시각적 스타일링은 매우 빠르지만, ARIA 속성이나 시맨틱 HTML을 자동으로 추가해 주지 않는다는 단점이 있다 [7]. 따라서 개발자가 항상 적절한 ARIA 속성과 시맨틱 요소를 직접 추가하는 것이 주요 모범 사례(Best Practice)로 꼽힌다 [8].
- **[[Headless UI|Headless UI]] 패턴**: [[Radix UI|Radix UI]]나 Headless UI와 같은 라이브러리는 복잡한 상태 관리와 접근성 기능을 기본적으로 제공하면서 스타일링 권한만 개발자에게 위임하므로, 브랜드 맞춤형이면서도 완벽한 접근성을 갖춘 UI 시스템을 구축하는 데 매우 유리하다 [9].
- **복합 컴포넌트([[Compound Components|Compound Components]])**: 컴포넌트 내부 컨텍스트(Context)를 공유함으로써 사용자가 직접 ID를 조작하지 않아도 `aria-controls``aria-labelledby`를 자동으로 연결하여 접근성 적용을 단순화할 수 있다 [10].
- **대규모 엔터프라이즈의 접근성 관리 (Uber 및 Shopify 사례)**: Shopify의 Polaris 디자인 시스템과 Uber의 Base Web은 키보드 탐색과 화면 판독기 지원을 핵심 기능으로 제공한다 [2, 11, 12]. 특히 Uber는 VoiceOver, TalkBack, ARIA 역할 등 여러 접근성 API의 수백 가지 속성을 정확하게 유지하기 위해, AI 에이전트를 통해 [[Figma|Figma]] 디자인 파일에서 즉각적으로 스펙(Spec) 문서를 자동 생성하는 시스템을 구축해 규모의 한계를 극복했다 [13-16].
## 🔗 Knowledge Connections
- **Related Topics:** [[Headless Components|Headless Components]], Compound Components, Design Tokens, [[Tailwind CSS|Tailwind CSS]]
- **Projects/Contexts:** [[Shopify Polaris|Shopify Polaris]], Uber Base Web, [[Radix UI|Radix UI]]
- **Contradictions/Notes:** 소스는 복합 컴포넌트(Compound Components) 패턴이 ARIA 속성 자동 연결 등을 통해 접근성을 개선해 주지만 [10], 사용자에게 너무 많은 유연성을 부여할 경우 하위 컴포넌트의 순서를 임의로 변경하거나 누락하여 오히려 접근성과 UX를 손상시킬 수 있다고 경고한다 [17].
---
*Last updated: 2026-04-26*
@@ -1,28 +0,0 @@
# [[Accessible UI Libraries|Accessible UI Libraries]]
## 📌 Brief Summary
접근성([[Accessibility|Accessibility]], A11y)을 기본적으로 갖춘 UI 라이브러리는 스크린 리더 호환성, 키보드 내비게이션, ARIA 속성 등을 내장하여 모든 사용자가 포용적으로 사용할 수 있도록 설계된 컴포넌트 모음입니다 [1-3]. Shopify의 Polaris, Uber의 Base Web, Chakra UI, Headless UI([[Radix UI|Radix UI]] 등) 등이 대표적이며, 이러한 라이브러리들은 확장 가능한 프론트엔드 환경에서 재사용 가능한 UI를 구축할 때 필수적인 역할을 합니다 [2, 4, 5]. 이들을 활용하면 팀이 처음부터 접근성 규칙을 구현하는 시간을 절약하고, 누구나 쉽게 접근 가능한 일관된 사용자 경험(UX)을 제공할 수 있습니다 [6-8].
## 📖 Core Content
* **주요 접근성 내장 UI 라이브러리 및 특징:**
* **Chakra UI:** ARIA 호환성을 기본적으로 갖추고 있으며, 키보드 내비게이션과 스크린 리더 사용을 완벽하게 지원하도록 설계되어 포용적인 애플리케이션을 구축하는 데 유리합니다 [2].
* **[[Shopify Polaris|Shopify Polaris]]:** WCAG 표준을 따르며 적절한 색상 대비, 키보드 내비게이션, 스크린 리더 호환성을 제공합니다 [9]. 또한 ARIA 라벨과 같은 접근성 기능이 사전 구축된 컴포넌트로 제공됩니다 [7].
* **[[Uber Base Web|Uber Base Web]]:** 키보드 내비게이션이 안정적으로 작동하고 스크린 리더와 잘 호환되도록 보장하여, 개발자가 모든 방문자에게 적합한 제품을 구축할 수 있게 돕습니다 [1, 4].
* **Foundation:** 기본적으로 접근성이 내장되어 있으며, 모든 코드 스니펫에 ARIA 속성이 포함되어 제공되므로 기기나 사용자의 능력에 관계없이 훌륭한 경험을 보장합니다 [3].
* **Headless UI (Radix UI 등):** 복잡한 컴포넌트(드롭다운, 다이얼로그 등)에 대해 상태 관리 및 접근성 기능만 제공하고 스타일링은 개발자에게 완전히 일임합니다 [5]. [[Tailwind CSS|Tailwind CSS]]와 결합하면 높은 접근성과 브랜드 특화된 UI 라이브러리를 구축하는 데 강력한 힘을 발휘합니다 [5].
* **재사용 가능한 UI 컴포넌트와 접근성(A11y)의 중요성:**
* 재사용 가능한 컴포넌트 설계 시 '접근성 우선(Accessibility First)'은 타협할 수 없는 필수 요소입니다 [10]. 탭(Tab) 순서, 의미 있는 포커스 관리, 올바른 시맨틱 역할(Roles)과 라벨링은 기본적으로 컴포넌트 DNA에 포함되어야 합니다 [10, 11].
* 접근성이 확보된 컴포넌트는 팀이 접근성을 처음부터 다시 고민하지 않고도 자신 있게 소프트웨어를 출시할 수 있는 가속기(Accelerator) 역할을 합니다 [6].
* **규모에 따른 접근성 사양 유지의 과제와 자동화:**
* Uber와 같은 대규모 기업에서는 VoiceOver, TalkBack, ARIA 등 플랫폼별로 수백 개의 접근성 속성을 수동으로 유지·관리하는 데 한계가 있습니다 [12].
* 이를 해결하기 위해 AI 에이전트와 [[Figma|Figma]] Console MCP를 연결하여 컴포넌트 구조를 스캔하고, 단 2분 만에 완벽한 스크린 리더 접근성 사양과 문서를 자동 생성하는 시스템(uSpec)을 구축하여 문서화 병목 현상을 해결했습니다 [13-15].
## 🔗 Knowledge Connections
- **Related Topics:** [[Headless Components|Headless Components]], [[Design Tokens|Design Tokens]] & Theming
- **Projects/Contexts:** [[Shopify Polaris|Shopify Polaris]], Uber Base Web, Chakra UI, [[Radix UI|Radix UI]]
- **Contradictions/Notes:** Tailwind CSS 자체는 강력한 유틸리티 기반 스타일링을 제공하지만, ARIA 속성이나 시맨틱 HTML을 자동으로 추가해주지는 않으므로 접근성을 간과하는 것이 흔한 함정(Pitfall)으로 지적됩니다. 따라서 Tailwind를 사용할 때는 반드시 시맨틱 요소를 직접 추가하거나, 접근성 기능이 내장된 Headless UI 라이브러리를 함께 사용하는 것이 권장됩니다 [5, 16].
---
*Last updated: 2026-04-26*
@@ -1,30 +0,0 @@
# [[Atomic Design|Atomic Design]]
## 📌 Brief Summary
Atomic Design(아토믹 디자인)은 브래드 프로스트(Brad Frost)가 고안한 디자인 방법론으로, 사용자 인터페이스(UI)를 응집력 있는 전체이자 부분의 집합으로 동시에 생각할 수 있게 해주는 멘탈 모델입니다 [1-3]. 이 방법론은 인터페이스를 원자(Atoms), 분자(Molecules), 유기체(Organisms), 템플릿(Templates), 페이지(Pages)라는 5개의 계층적 단계로 나누어 효과적이고 의도적인 디자인 시스템을 구축하도록 돕습니다 [4, 5]. React와 같은 모던 컴포넌트 아키텍처와 결합하여 일관성을 강제하고, 디자인 시스템의 재사용성을 높이며, 확장 가능한 폴더 구조를 구축하는 데 널리 활용됩니다 [6-8].
## 📖 Core Content
* **5단계의 컴포넌트 계층 구조**:
* **원자 (Atoms)**: 더 이상 쪼갤 수 없는 UI의 기본 구성 요소입니다 [1, 5]. HTML 태그(예: input, label, button)나 React의 기본 함수형 컴포넌트에 해당하며, 각기 고유한 속성을 가집니다 [9, 10].
* **분자 (Molecules)**: 원자들의 결합으로 이루어진 비교적 단순한 UI 컴포넌트 그룹입니다(예: 라벨 + 입력창 + 버튼 = 검색 폼) [5, 10, 11]. 단일 책임 원칙(Single Responsibility Principle)을 장려하여 "한 가지 일을 잘 수행하도록" 함으로써 테스트와 재사용성을 용이하게 합니다 [12].
* **유기체 (Organisms)**: 분자, 원자, 혹은 다른 유기체들로 구성된 복잡한 컴포넌트로, 인터페이스의 뚜렷한 독립적 섹션을 형성합니다(예: 웹사이트 헤더, 제품 그리드) [5, 10, 13, 14].
* **템플릿 (Templates)**: 컴포넌트들을 레이아웃에 배치하고 디자인의 근본적인 콘텐츠 구조(뼈대)를 명확히 하는 페이지 레벨의 객체입니다 [5, 10, 15, 16]. 최종 콘텐츠보다는 기본 골격에 집중합니다 [16].
* **페이지 (Pages)**: 템플릿에 실제 대표 콘텐츠를 주입한 구체적 인스턴스입니다. 최종 UI를 보여주고 기초 디자인 시스템의 효과와 복원력을 테스트하며 콘텐츠의 동적 변형(예: 데이터 길이에 따른 변화)을 명확히 합니다 [5, 10, 17-19].
* **Atomic Design의 핵심 이점 및 특징**:
* **맥락의 전환**: 추상적인 요소(원자)를 조작하는 동시에 그것들이 모여 구체적인 최종 결과물(페이지)에 미치는 영향을 빠르게 파악하고 테스트할 수 있도록 돕습니다 [20, 21].
* **구조와 콘텐츠의 분리**: UI의 콘텐츠 구조 스켈레톤(템플릿)과 최종 콘텐츠(페이지) 사이의 깔끔한 분리를 제공하면서도 둘의 상호작용을 고려하게 합니다 [22, 23].
* **보편적 적용성**: 웹 전용 기술(CSS, [[JavaScript|JavaScript]] 구조 등)에 국한되지 않으며, Instagram과 같은 네이티브 모바일 앱을 포함한 모든 소프트웨어 인터페이스 설계에 적용할 수 있습니다 [24-26].
* **비선형적 접근**: 단순히 1단계에서 5단계로 순차적으로 진행하는 선형 프로세스가 아니라, 전체와 부분을 동시에 설계하기 위한 멘탈 모델로 접근해야 합니다 [1, 2].
* **React 확장성 및 아키텍처에서의 활용**:
* React의 컴포넌트 트리와 완벽하게 대칭을 이루어 디자인 시스템을 구축하는 근본적인 모델이 됩니다 [6].
* 성공적인 엔터프라이즈 팀들은 원자 단위의 순수함과 재사용성을 유지하기 위해 UI 라이브러리 계층에는 Atomic Design을 활용하고, 비즈니스 로직이 들어가는 애플리케이션 코드에는 기능 분할 설계([[Feature-Sliced Design|Feature-Sliced Design]], FSD) 등 기능 기반 구조를 혼합하여 설계합니다 [10, 27].
## 🔗 Knowledge Connections
- **Related Topics:** [[Component-Based Design|Component-Based Design]], Feature-Sliced Design (FSD), Compound Components, [[Design Systems|DesignSystems]]
- **Projects/Contexts:** [[React Frontend Architecture|React Frontend Architecture]], [[Reusable UI Component Libraries|Reusable UI Component Libraries]]
- **Contradictions/Notes:** 소스에 따르면 Atomic Design은 시각적 일관성과 재사용성을 달성하는 데는 매우 강력하지만, 복잡한 비즈니스 로직을 가진 컴포넌트를 이 5가지의 엄격한 범주에 억지로 끼워 맞추려다 보면 어려움에 직면할 수 있다는 한계도 지적됩니다 [10]. 이에 대한 보완책으로 [[Headless UI|Headless UI]]나 [[Compound Components|Compound Components]] 패턴이 현대 프론트엔드 환경에서 함께 권장됩니다 [28, 29].
---
*Last updated: 2026-04-26*
@@ -1,25 +0,0 @@
# [[Automatic Batching|Automatic Batching]]
## 📌Brief 시 Summary
Automatic [[Batching|Batching]](자동 배칭)은 React 18에 도입된 기능으로, 여러 상태(State) 업데이트를 하나의 리렌더링으로 그룹화하여 처리하는 성능 최적화 기법입니다 [1-3]. 이전 버전에서는 React의 네이티브 이벤트 핸들러 내의 업데이트만 배칭되었으나, React 18부터는 프로미스(Promise), setTimeout, 비동기 작업 등 출처와 무관하게 모든 상태 업데이트를 자동으로 배칭합니다 [2, 4-6]. 이를 통해 불필요한 리렌더링과 [[Virtual DOM|Virtual DOM]]의 비교 연산(diffing)을 최소화하여 애플리케이션의 성능과 UI 응답성을 크게 향상시킵니다 [4, 7].
## 📖 Core Content
* **작동 원리 및 도입 배경:**
React 18 이전에는 `onClick`과 같은 React 내부 이벤트 핸들러에서 발생하는 상태 업데이트만 배칭 처리가 되었습니다 [2, 6]. 따라서 `setTimeout`이나 비동기 API 호출 내에서 상태를 여러 번 업데이트할 경우, 각 업데이트마다 개별적인 리렌더링이 발생하여 성능 저하의 원인이 되었습니다 [2, 8]. React 18의 자동 배칭 기능은 이벤트 출처와 상관없이 모든 상태 업데이트를 하나로 묶어(Batch) 단 한 번의 렌더링과 DOM 업데이트만 트리거합니다 [3, 7, 9, 10].
* **렌더링 성능 최적화 효과 ("React가 빠른 이유"):**
자동 배칭은 여러 상태 변경이 짧은 시간 안에 연속적으로 발생할 때 불필요한 리렌더링의 수를 줄여줍니다 [10, 11]. 리렌더링 횟수가 감소하면 Virtual DOM의 비교 연산(Diffing)과 CPU 작업량이 최소화됩니다 [1, 4]. 실제로 데이터 집약적인 대시보드 환경에서 자동 배칭을 적용한 결과, 전체 렌더링 횟수가 약 40% 감소하고 피크 로드 시 프레임 속도가 25% 향상되는 등 눈에 띄는 성능 개선을 보여주었습니다 [1, 12]. 이는 "Reflow"와 "Repaint"를 유발하는 브라우저의 DOM 조작 빈도를 줄이는 핵심적인 최적화 원리 중 하나입니다 [7].
* **자동 배칭 제어 및 예외 처리 (Opt-Out):**
개발자가 의도적으로 자동 배칭을 우회하고 상태 업데이트 즉시 DOM에 반영해야 하는 상황이 존재할 수 있습니다. 예를 들어, 사용자의 폼 입력에 즉각적인 피드백을 주거나 렌더링 직후 DOM 요소의 크기를 측정해야 하는 경우입니다 [13]. 이때는 React DOM에서 제공하는 `[[flushSync|flushSync]]` API를 사용하여 강제로 즉각적인 동기적 리렌더링을 발생시킬 수 있습니다 [12-15]. 반대로, 긴급하지 않은 대규모 업데이트(예: 리스트 필터링)의 경우 `[[startTransition|startTransition]]`을 사용하여 우선순위를 낮추고 UI 차단을 방지할 수 있습니다 [12, 13].
* **주의사항 및 디버깅:**
자동 배칭은 기본적으로 제공되는 최적화지만, 일부 서드파티 상태 관리 도구나 UI 라이브러리가 React의 이벤트 시스템을 우회하는 방식으로 동작할 경우 배칭이 제대로 적용되지 않을 수 있습니다 [16, 17]. 이러한 예외 상황을 식별하기 위해서는 React DevTools Profiler를 사용하여 컴포넌트의 렌더링 횟수와 업데이트 트리거를 모니터링하는 것이 권장됩니다 [16].
## 🔗 Knowledge Connections
- **Related Topics:** [[Virtual DOM|Virtual DOM]], [[React가 빠른 이유|React가 빠른 이유]], Reflow / Repaint 최소화 방법
- **Projects/Contexts:** [[React 18|React 18]], [[Performance Optimization|Performance Optimization]]
- **Contradictions/Notes:** 자동 배칭은 성능을 크게 향상시키지만 무조건적으로 유용한 것은 아닙니다. 폼의 입력 값 업데이트나 요소 포커싱처럼 사용자에게 지연 없는 즉각적 피드백을 제공해야 하는 필수적인 상황에서는 `flushSync`를 사용해 배칭을 해제해야 하며, 이를 남용할 경우 배칭으로 얻는 성능 이점을 상쇄할 수 있으므로 주의해야 합니다 [13, 18]. 또한 서드파티 라이브러리 통합 시 React 이벤트 시스템을 우회하면 자동 배칭이 무력화될 수 있다는 함정이 존재합니다 [17].
---
*Last updated: 2026-04-25*
@@ -1,28 +0,0 @@
# [[Automatic Batching을 통한 React 18 성능 최적화|Automatic Batching을 통한 React 18 성능 최적화]]
## 📌 Brief Summary
[[Automatic Batching|Automatic Batching]]은 React 18에서 도입된 성능 최적화 기능으로, 여러 상태(State) 업데이트를 단일 리렌더링으로 묶어서 처리합니다 [1-3]. 이전 버전과 달리 프로미스(Promises), `setTimeout`, 비동기 작업 등 업데이트 출처에 관계없이 모든 상태 변경을 일괄 처리하여 불필요한 리렌더링을 방지합니다 [4-6]. 이를 통해 [[Virtual DOM|Virtual DOM]]의 비교(diffing) 작업을 최소화하고 애플리케이션의 성능과 UI 응답성을 크게 향상시킵니다 [1, 4, 7].
## 📖 Core Content
* **작동 원리 및 이전 버전과의 차이점:**
React 18 이전에는 `onClick`이나 `onChange` 같은 네이티브 React 이벤트 핸들러 내에서 발생하는 상태 업데이트만 일괄 처리(배칭)되었으며, `setTimeout`이나 Promise와 같은 비동기 작업에서는 각 업데이트마다 개별적인 리렌더링이 발생했습니다 [2, 6]. 하지만 React 18부터는 자동 배칭(Automatic Batching)이 기본으로 활성화되어, 비동기 작업이나 타임아웃 등 모든 환경에서의 상태 업데이트를 하나의 렌더링 사이클로 그룹화합니다 [4, 5, 8].
* **성능 향상 및 Virtual DOM 최적화:**
여러 상태 변경을 하나로 결합함으로써 React는 Virtual DOM의 diffing 연산과 불필요한 DOM 업데이트 횟수를 최소화합니다 [1, 4, 7]. 실제 데이터 집약적인 대시보드를 대상으로 한 벤치마크 결과에 따르면, 자동 배칭을 활성화할 경우 최대 부하 상태에서 총 렌더링 횟수가 약 40% 감소하고 프레임 속도는 25% 향상되는 성능 개선을 보였습니다 [1, 9]. 이는 깊게 중첩된 컴포넌트를 가진 복잡한 애플리케이션에서 특히 유용합니다 [10].
* **렌더링 제어 API (`[[flushSync|flushSync]]` 및 `[[startTransition|startTransition]]`):**
자동 배칭이 기본 동작이지만, React는 렌더링 시점을 제어할 수 있는 API를 제공합니다 [9, 11].
* `flushSync`: 폼 입력값을 즉시 업데이트하여 사용자에게 지연 없이 보여주거나, 상태 변경 직후 DOM 요소를 포커스 및 측정해야 할 때 자동 배칭을 우회하여 동기적 리렌더링을 강제합니다 [9, 12, 13].
* `startTransition`: 리스트 필터링과 같이 긴급하지 않은 상태 업데이트를 표시하여 타이핑이나 클릭 등 우선순위가 높은 상호작용을 차단하지 않도록 양보(yield)합니다 [9, 12].
* **모니터링 및 베스트 프랙티스:**
성능 최적화를 극대화하려면 관련된 업데이트를 같은 이벤트 내에 그룹화하고 함수형 상태 업데이트(`setState(prev => new)`)를 사용하는 것이 좋습니다 [14]. 예상치 못한 리렌더링이 발생한다면 타사 라이브러리가 React의 이벤트 시스템을 우회하고 있지 않은지 확인해야 하며, React DevTools Profiler를 통해 상호작용에 따른 렌더링 횟수와 업데이트 원인을 디버깅하고 모니터링할 수 있습니다 [15-17].
## 🔗 Knowledge Connections
- **Related Topics:** `[[Virtual DOM|Virtual DOM]]`, `flushSync`, `startTransition`, `[[Concurrent Rendering|Concurrent Rendering]]`, `useMemo / useCallback`
- **Projects/Contexts:** `데이터 집약적 대시보드 성능 최적화`, `React 18 애플리케이션 마이그레이션`
- **Contradictions/Notes:** 자동 배칭은 대부분의 경우 렌더링 성능을 개선하지만, 즉각적인 DOM 반영이 필요한 예외 상황에서는 방해가 될 수 있습니다. 이 경우 `flushSync`를 사용해 강제로 배칭을 해제할 수 있으나, 이를 남용할 경우 배칭으로 얻는 성능상 이점이 무효화될 수 있으므로 극히 제한적으로 사용해야 한다고 경고하고 있습니다 [11, 12, 14].
---
*Last updated: 2026-04-25*
@@ -1,32 +0,0 @@
# [[BEM (Block Element Modifier)|BEM (Block Element Modifier]]
## 📌 Brief Summary
BEM(Block Element Modifier)은 모듈식이고 재사용 가능하며 충돌 없는 UI 컴포넌트를 구축하기 위해 고안된 검증된 CSS 아키텍처 방법론이다 [1]. 깊게 중첩된 선택자 대신 평면적이고 명시적이며 스스로를 설명할 수 있는 클래스 명명 규칙을 도입하여 CSS를 구조화한다 [2, 3]. 이를 통해 대규모 프론트엔드 프로젝트에서 전역 네임스페이스 충돌을 방지하고 CSS의 예측 가능성과 유지보수성을 높이는 것을 핵심 목적으로 한다 [4, 5].
## 📖 Core Content
* **BEM의 구조 및 명명 규칙:**
* BEM은 독립적으로 의미를 가지는 재사용 가능한 UI 컴포넌트인 '블록(Block)', 블록에 종속되어 독립적으로 존재할 수 없는 하위 요소인 '엘리먼트(Element)', 그리고 모양이나 상태의 변화를 나타내는 '모디파이어(Modifier)'로 구성된다 [3, 6, 7].
* 엘리먼트는 이중 밑줄(`__`)로 구분하고(예: `card__title`), 모디파이어는 이중 하이픈(`--`)으로 구분한다(예: `button--primary`) [6-8].
* **BEM의 장점 및 유지보수성 기여:**
* 낮은 결합도(Low Coupling)와 높은 응집도(High Cohesion)를 촉진하여 컴포넌트를 격리하고, 스타일이 깊은 DOM 중첩에 의존하지 않게 만든다 [5, 9].
* 평면적인(flat) 선택자 계층 구조를 생성하여 브라우저 CSS 엔진의 광범위한 트리 탐색을 방지하므로 렌더링 성능에 유리하다 [9, 10].
* 클래스 이름 자체가 문서 역할을 하여(Self-documenting) 새로운 개발자도 해당 클래스가 어느 컴포넌트의 어떤 변형인지 즉시 파악할 수 있으므로 팀 협업과 안전한 리팩토링을 돕는다 [9, 11, 12].
* **한계 및 단점:**
* 가장 큰 취약점은 규율 준수를 전적으로 '사람의 강제(human enforcement)'에 의존한다는 점이다 [5, 13, 14].
* 개발자의 실수로 명명 규칙이 위반되거나 전역 스코프에서 블록 이름이 충돌할 위험이 존재한다 [13, 15].
* 클래스 이름이 길고 장황해질 수 있으며(verbosity), 사용하지 않는 데드 코드(dead code)를 빌드 파이프라인에서 자동으로 식별하고 제거하기 어렵다 [12-14].
* **실무 활용 및 현대적 대안과의 비교:**
* 장황한 클래스명 작성의 불편함은 Sass나 Less 같은 CSS 전처리기의 중첩(nesting) 기능을 활용하여 완화할 수 있다 [16, 17].
* 최근의 React 등 컴포넌트 기반 환경에서는 BEM이 해결하려 했던 전역 CSS 충돌 문제를 자동으로 해결해주는 [[CSS Modules|CSS Modules]]가 선호되는 경향이 있다 [18, 19].
* 그러나 공유 유틸리티, 전역 디자인 시스템, 혹은 컴포넌트 라이브러리에서 테마를 덮어써야 하는 화이트라벨(whitelabel) 앱 환경 등에서는 BEM의 명시적 구조가 여전히 매우 유용하게 사용된다 [19-21].
## 🔗 Knowledge Connections
- **Related Topics:** [[CSS Modules|CSS Modules]], Tailwind CSS, CSS-in-JS, [[CSS Architecture|CSS Architecture]]
- **Projects/Contexts:** 대규모 프론트엔드 프로젝트 유지보수, 컴포넌트 기반 UI 설계, [[디자인 시스템 구축|디자인 시스템 구축]]
- **Contradictions/Notes:** BEM은 명시적이고 예측 가능한 스타일링을 제공하여 유지보수성을 극대화하지만 [1, 9], 인간의 수동 관리에 의존해야 한다는 명확한 한계가 존재한다 [5, 14]. 이로 인해 오늘날의 실무에서는 빌드 단계에서 자동으로 고유 클래스명을 보장하는 CSS Modules나, 유틸리티 클래스 기반으로 재사용성을 높인 [[Tailwind CSS|Tailwind CSS]]와 종종 비교되거나 상호 보완적으로 사용된다 [8, 21-23].
---
*Last updated: 2026-04-26*
-28
View File
@@ -1,28 +0,0 @@
# [[BEM|BEM]]
## 📌 Brief Summary
BEM(Block Element Modifier)은 모듈화되고 재사용 가능하며 충돌이 없는 UI 컴포넌트를 구축하기 위해 고안된 CSS 아키텍처 및 네이밍 규칙론입니다 [1]. 클래스 이름을 블록(Block), 요소(Element), 상태/변형(Modifier)이라는 세 가지 구성 요소로 명확히 나누어 작성함으로써 CSS의 전역 스코프(Global Scope)로 인해 발생하는 복잡성과 이름 충돌 문제를 방지합니다 [2-4]. 이를 통해 대규모 프론트엔드 프로젝트에서도 CSS를 예측 가능하고 유지보수하기 쉽게 관리할 수 있도록 돕습니다 [5].
## 📖 Core Content
- **BEM의 핵심 구성 요소:**
- **Block (블록):** `card`, `button`, `navigation` 등과 같이 스스로 의미를 가지며 독립적으로 재사용 가능한 UI 컴포넌트 단위입니다 [3]. 주변 DOM 구조에 의존하지 않고 기능해야 합니다 [3].
- **Element (요소):** 블록에 종속된 하위 구성 요소로, 독립적으로 존재할 수 없습니다 [6]. 이중 밑줄(`__`)을 사용하여 표기합니다(예: `card__title`, `card__image`) [6].
- **Modifier (모디파이어):** 블록이나 요소의 상태, 외관, 동작의 변화를 나타냅니다 [7]. 이중 하이픈(`--`)으로 표기합니다(예: `card--highlighted`, `button--disabled`) [7].
- **아키텍처적 이점:**
- **유지보수성과 예측 가능성:** 예기치 않은 스타일 덮어쓰기와 선택자 명시도(specificity) 충돌 문제를 방지하여 소위 '스파게티 스타일'이 되는 것을 막습니다 [2, 8].
- **평면적인 선택자(Flat Selectors):** 깊이 중첩된 선택자를 사용하지 않고 평면적이고 고유한 클래스명을 만들어내므로, 브라우저의 렌더링 성능이 향상되고 코드를 쉽게 읽을 수 있습니다 [9, 10].
- **협업 및 리팩토링 용이성:** 클래스 이름이 그 자체로 문서화(Self-documenting) 역할을 하여, 새로운 개발자가 컴포넌트의 경계를 즉시 파악할 수 있습니다 [11, 12]. 또한, 길고 고유한 네이밍 패턴 덕분에 'Ctrl+H(찾기/바꾸기)'와 같은 텍스트 교체 기능으로 리팩토링하기 매우 쉽습니다 [13].
- **실무 설계 원칙 및 한계점:**
- **가이드라인:** 과도하게 깊은 요소 체인(예: `block__elem1__elem2`)을 만드는 것을 지양해야 하며, 부모 선택자에 의존하는 문맥 의존적 스타일링(Context-Dependent Styling)은 피해야 합니다 [14, 15].
- **장황함(Verbosity) 극복:** BEM의 주된 비판 중 하나는 클래스 이름이 길고 장황해진다는 점입니다 [12]. 하지만 [[SCSS|SCSS]]나 Less 같은 CSS 전처리기를 사용하면 부모 참조(`&`)와 중첩(Nesting) 기능을 통해 BEM을 훨씬 효율적이고 깔끔하게 작성할 수 있습니다 [16, 17].
- **휴먼 에러의 한계:** BEM은 개발자의 자발적인 규칙 준수에 의존하는 '수동적인' 보장 방식입니다 [18, 19]. 따라서 프로젝트가 커지고 시간이 지날수록 규칙이 깨지거나 이름이 충돌할 위험성을 완전히 배제할 수는 없습니다 [18, 20].
## 🔗 Knowledge Connections
- **Related Topics:** [[CSS Modules|CSS Modules]], Tailwind CSS, SCSS, [[CSS Architecture|CSS Architecture]]
- **Projects/Contexts:** [[디자인 시스템 개념|디자인 시스템 개념]], 컴포넌트 기반 아키텍처 (React, Vue 등), [[Feature-Sliced Design (FSD)|Feature-Sliced Design (FSD]]
- **Contradictions/Notes:** 소스 문헌들에서는 BEM과 [[CSS Modules|CSS Modules]]의 근본적인 접근 방식을 비교하고 있습니다. BEM은 고유한 네이밍 패턴을 '수동으로' 작성하여 충돌을 막으려는 시도인 반면, CSS Modules는 빌드 시점에 해시된 고유 식별자를 생성해 스코프 제한을 '자동으로' 해결합니다 [19, 21]. 이러한 이유로 현대의 React/TypeScript 기반 생태계에서는 BEM의 원래 목적이 CSS Modules로 대체될 수 있어 CSS Modules가 더 자연스럽다는 주장이 있습니다 [22, 23]. 그러나 여전히 글로벌 디자인 시스템의 토큰 및 유틸리티 구성이나 리팩토링 관점에서는 BEM이 유용하다는 시각도 공존합니다 [13, 24].
---
*Last updated: 2026-04-26*
@@ -1,33 +0,0 @@
# [[Building Reusable UI Components|Building Reusable UI Components]]
## 📌 Brief Summary
재사용 가능한 UI 컴포넌트는 여러 프로젝트와 위치에서 코드를 크게 수정하지 않고도 사용할 수 있는 독립적이고 이식성(Portable)과 예측 가능성(Predictable)이 뛰어난 UI 구성 요소입니다 [1]. 이는 단일 책임을 가지며 명확한 API(Props)와 접근성([[Accessibility|Accessibility]])을 갖추어 확장 가능하고 일관성 있는 디자인 시스템을 구축하는 핵심 역할을 합니다 [2, 3]. 최신 React 생태계에서는 복잡성을 줄이기 위해 단순한 Prop 전달을 넘어서, 컴파운드 컴포넌트나 헤드리스 컴포넌트와 같은 고급 합성 패턴을 활용하여 재사용성을 극대화합니다 [4, 5].
## 📖 Core Content
* **재사용 가능한 컴포넌트의 4가지 핵심 원칙 (Four Golden Rules)**:
* **단일 책임 (Single Responsibility):** 각 컴포넌트는 한 가지 기능만 잘 수행하도록 만들어 버그를 줄이고 재사용성을 높여야 합니다 [3].
* **상속보다 합성 (Composition Over Inheritance):** 의견이 배제된(unopinionated) 기본 컴포넌트들을 블록처럼 조립하여 더 큰 컴포넌트를 구성해야 합니다 [3].
* **명확한 계약 (Explicit Contracts):** 컴포넌트가 받는 값(Props)과 반환하는 이벤트(Callbacks)의 API를 명확히 정의하여 부작용을 방지해야 합니다 [3, 6].
* **접근성 우선 (Accessibility First):** 키보드 내비게이션, ARIA 역할(Roles), 포커스 관리 등 스크린 리더 및 모든 사용자를 위한 접근성을 기본적으로 내장해야 합니다 [3, 7].
* **상태 관리 및 API 설계 ([[State|State]] [[Boundaries|Boundaries]] & API Design)**:
* Prop 기반의 API는 요구사항이 늘어날수록 수많은 상태 변수(Prop Soup)를 발생시켜 확장을 어렵게 만듭니다 [6, 8]. 의도에 맞는 Prop 이름을 사용하고 안전한 기본값(Defaults)을 설정해야 합니다 [6].
* 툴팁 토글과 같은 로컬 UI 상태는 컴포넌트 내부에 유지하되, 필터링이나 데이터 호출과 같은 비즈니스 로직은 상위 부모 컴포넌트로 올려야(Push up) 재사용성이 높아집니다 [9].
* **재사용성을 극대화하는 고급 React 패턴 (Scalable Component Patterns)**:
* **컴파운드 컴포넌트 ([[Compound Components|Compound Components]]):** 아코디언(Accordion)이나 탭(Tabs)처럼 여러 하위 컴포넌트가 Context를 통해 암시적으로 상태를 공유하도록 구성하여, 소비자가 레이아웃을 유연하게 제어할 수 있게 합니다 [10-12].
* **헤드리스 컴포넌트 ([[Headless Components|Headless Components]]):** 시각적인 마크업(UI) 없이 상태와 동작 로직만 제공하여, 디자인 시스템과 무관하게 접근성 높고 재사용 가능한 컴포넌트를 만들 수 있습니다 [13-15].
* **렌더 프롭스 ([[Render Props|Render Props]]):** 함수를 자식 요소로 전달하여 로직을 공유하고 렌더링에 대한 완전한 제어권을 사용자에게 부여합니다 [15, 16].
* **슬롯 및 영역 (Slots / Regions):** 소비자가 직접 콘텐츠를 끼워 넣을 수 있는 의도적인 빈 공간(예: 헤더, 푸터)을 제공하여 Prop의 과부하를 막습니다 [14].
* **스타일링과 테마 적용 (Styling & Theming)**:
* 재사용 가능한 컴포넌트는 하드코딩된 스타일을 피하고, 색상이나 간격 등의 디자인 토큰([[Design Tokens|Design Tokens]])을 기반으로 브랜드의 룩을 상속받아야 합니다 [17].
* 구조를 캡슐화하면서도 클래스 이름이나 스타일 Prop을 주입할 수 있는 훅을 노출하여, 코드를 포크(Fork)하지 않고도 여러 제품 스킨이나 다크 모드 테마에 유연하게 대응하도록 설계해야 합니다 [17, 18].
## 🔗 Knowledge Connections
- **Related Topics:** [[Compound Components|Compound Components]], Headless Components, Atomic Design, [[Design Tokens|Design Tokens]]
- **Projects/Contexts:** [[Shopify Polaris|Shopify Polaris]] (재사용 가능한 컴포넌트와 접근성을 제공하여 일관된 앱 UI를 구축하는 쇼피파이의 디자인 시스템 [19, 20]), [[Uber Base Web|Uber Base Web]] (다양한 요구사항에 대응하기 위해 모든 하위 요소의 스타일과 기능을 제어할 수 있는 'Overrides' 패턴을 구현한 React 컴포넌트 라이브러리 사례 [21, 22])
- **Contradictions/Notes:** 컴파운드 컴포넌트는 뛰어난 레이아웃 구성의 자유도를 제공하지만 [10], 지나친 자유도는 UX 일관성을 해칠 수 있으며, 단순하고 구조가 고정된 컴포넌트(예: 버튼, 아이콘)에 사용할 경우 불필요한 추상화와 유지보수 비용만 증가시키게 되므로 상황에 맞게 적용해야 합니다 [23-25].
---
*Last updated: 2026-04-26*
@@ -1,42 +0,0 @@
## 📌 Brief Summary
'Bulletproof React'는 프로덕션 수준의 React 애플리케이션을 구축하기 위한 확장 가능하고 강력한 아키텍처 가이드라인이다. React의 자유도로 인해 발생하는 일관성 없는 구조 문제를 해결하기 위해 기능(Feature) 기반의 모듈화와 명확한 계층 분리라는 주관적인(Opinionated) 베스트 프랙티스를 제시한다.
## 📖 Core Content
1. **아키텍처 철학 (Scalability & Predictability)**
- React는 프레임워크가 아닌 라이브러리이므로 구조적 선택의 책임이 개발자에게 있다.
- Bulletproof React는 팀 규모와 코드베이스가 커져도 유지보수가 가능하도록 명확한 경계(Boundaries)와 일관된 작업 방식을 제공한다.
2. **기능 기반 구조 (Feature-Based Structure)**
- 기술적 역할(Components, Hooks, Styles)이 아닌 비즈니스 기능(Feature) 단위로 코드를 그룹화한다.
- 각 기능 폴더 내에 해당 기능에 필요한 컴포넌트, API, 상태, 타입, 유틸리티를 독립적으로 배치하여 응집도를 높인다.
3. **계층화된 아키텍처 (Layered Architecture)**
- 프로젝트 표준, 프로젝트 구조, 컴포넌트/스타일링, API 계층, 상태 관리, 테스트, 보안 등 프론트엔드 전반의 레이어를 규격화한다.
- 특정 기술에 얽매이지 않고 원칙(Principles)에 집중하여 라이브러리 교체가 용이한 구조를 지향한다.
4. **유연한 적용 (Guideline, Not Template)**
- 강제적인 보일러플레이트가 아니며, 팀의 요구사항과 프로젝트 규모에 맞게 선택적으로 적용할 수 있는 가이드라인 역할을 수행한다.
## ⚖️ Trade-offs & Caveats
- **규칙의 파편화 위험**: 프레임워크가 아닌 가이드라인이므로, 팀 내에서 합의된 수준을 넘어서는 자의적인 해석이 발생할 경우 구조적 일관성이 깨질 수 있다.
- **초기 학습 곡선**: 폴더 구조가 깊어지고 관심사 분리가 엄격해짐에 따라, 기존의 플랫한 구조에 익숙한 개발자들에게는 초기 적응 시간이 필요하다.
- **오버헤드**: 매우 작은 규모의 프로젝트나 단순한 MVP 단계에서는 이러한 엄격한 분리가 오히려 과도한 보일러플레이트로 느껴질 수 있다.
## 🔗 Knowledge Connections
### Related Concepts
- **Feature-Based Structure**: 비즈니스 도메인 단위의 코드 응집도 향상 기법 (관계: 핵심 구현 패턴)
- **Feature-Sliced Design (FSD)**: 기능 기반 구조를 더 체계화한 고급 아키텍처 방법론 (관계: 확장 발전 형태)
- **Scalable React Architecture**: 대규모 시스템을 위한 설계 철학 (관계: 상위 목표)
### Deeper Research Questions
1. 기능 기반 구조에서 여러 기능 간에 공통으로 사용되는 로직(Shared)의 의존성 역전은 어떻게 관리하는가?
2. API 계층과 상태 관리 레이어의 물리적 분리가 단위 테스트의 고립성 확보에 어떤 영향을 미치는가?
3. 대규모 리팩토링 시, 기능 단위로 쪼개진 모듈이 파일 유형 기반 구조보다 안전한 이유는 무엇인가?
4. 아키텍처가 제시하는 '명확한 경계'를 강제하기 위해 ESLint 등의 도구를 어떻게 활용할 수 있는가?
5. 서버 컴포넌트(RSC) 환경에서 Bulletproof React의 폴더 구조 전략은 어떻게 진화해야 하는가?
### Practical Application Contexts
- **신규 프로젝트 셋업**: 초기 폴더 구조 및 레이어링 표준안으로 채택.
- **레거시 리팩토링**: 복잡해진 코드베이스를 기능 단위로 점진적으로 격리 및 구조화.
### Adjacent Topics
- **Clean Architecture in Frontend**
- **Domain-Driven Design (DDD)**
- **Monorepo Management Strategies**
@@ -1,32 +0,0 @@
# [[CSR vs SSR vs SSG|CSR vs SSR vs SSG]]
## 📌 Brief Summary
CSR(클라이언트 사이드 렌더링), SSR(서버 사이드 렌더링), SSG(정적 사이트 생성)는 웹 애플리케이션의 HTML 콘텐츠가 언제, 어디서 생성되어 사용자에게 전달되는지를 결정하는 핵심적인 웹 렌더링 전략입니다 [1-3]. CSR은 브라우저에서 [[JavaScript|JavaScript]]를 통해 동적으로 UI를 구축하며, SSR은 사용자의 요청마다 서버에서 전체 HTML을 실시간으로 생성합니다 [2]. 반면 SSG는 배포 전 빌드 시점에 모든 HTML 페이지를 미리 생성하여 CDN을 통해 정적 파일로 제공합니다 [2]. 각 렌더링 방식은 초기 로드 속도, SEO(검색 엔진 최적화), 서버 부하, 그리고 상호작용성 측면에서 서로 다른 장단점과 최적의 사용 사례를 가집니다 [4-6].
## 📖 Core Content
**클라이언트 사이드 렌더링 (CSR, Client-Side Rendering)**
* **작동 원리**: 서버는 최소한의 빈 HTML 뼈대와 함께 전체 JavaScript 번들을 브라우저에 전송합니다 [4, 7, 8]. 브라우저가 이 JavaScript를 다운로드하고 실행하여 데이터를 가져오고 DOM을 동적으로 구축합니다 [4, 8, 9].
* **장점**: 초기 로드가 완료된 후에는 페이지 새로고침 없이 즉각적인 화면 전환이 가능하여 매끄럽고 상호작용이 풍부한 앱과 같은 사용자 경험을 제공합니다 [7, 10, 11]. 렌더링의 무거운 작업을 브라우저가 처리하므로 서버 부하와 호스팅 비용을 줄일 수 있습니다 [10, 12].
* **단점**: 브라우저가 큰 JavaScript 번들을 모두 실행하기 전까지는 빈 화면이 표시될 수 있어 초기 로드 속도(First Contentful Paint)가 느립니다 [7, 10, 13]. 또한 검색 엔진 크롤러가 초기에 빈 페이지를 보게 되므로 SEO에 불리할 수 있습니다 [7, 14, 15].
* **적합한 사용 사례**: SEO가 중요하지 않으며 고도의 상호작용이 필요한 로그인 기반의 내부 대시보드, [[SaaS|SaaS]] 플랫폼, 싱글 페이지 애플리케이션(SPA) 등에 적합합니다 [4, 10, 16, 17].
**서버 사이드 렌더링 (SSR, Server-Side Rendering)**
* **작동 원리**: 사용자가 페이지를 요청할 때마다 서버에서 데이터를 가져와 완전히 렌더링된 HTML 문서를 생성하여 브라우저에 전송합니다 [18-20]. 브라우저는 이 HTML을 즉시 표시하지만, 상호작용을 위해서는 추가로 JavaScript를 다운로드하여 HTML에 연결하는 '하이드레이션([[Hydration|Hydration]])' 과정을 거쳐야 합니다 [18, 19, 21-23].
* **장점**: 검색 엔진이 완성된 HTML 콘텐츠를 즉시 크롤링할 수 있어 SEO에 매우 유리합니다 [18, 24, 25]. 사용자가 의미 있는 콘텐츠를 빠르게 볼 수 있으며(빠른 FCP), 항상 최신 상태의 동적 데이터를 반영할 수 있습니다 [18, 24, 25].
* **단점**: 모든 요청마다 서버에서 렌더링 로직을 실행해야 하므로 트래픽이 급증할 때 서버 부하와 인프라 관리 복잡성이 커집니다 [18, 21, 26, 27]. 또한, 하이드레이션 과정이 완료되기 전까지는 사용자가 버튼을 클릭해도 반응하지 않는 등 상호작용 지연(Time to Interactive) 현상이 발생할 수 있습니다 [18, 21, 23].
* **적합한 사용 사례**: 실시간 데이터 업데이트와 우수한 SEO 최적화가 동시에 필요한 뉴스 사이트, 콘텐츠 위주의 웹사이트, 전자상거래 제품 페이지 등에 이상적입니다 [24, 28, 29].
**정적 사이트 생성 (SSG, Static Site Generation)**
* **작동 원리**: 사용자의 요청 시점이 아니라, 애플리케이션의 빌드 과정에서 모든 HTML 페이지를 미리 생성(Pre-build)해 둡니다 [30-32]. 생성된 정적 파일은 CDN을 통해 배포되어 전 세계 사용자에게 즉각적으로 제공됩니다 [30, 33, 34].
* **장점**: 서버 측 연산 과정이 없으므로 가장 빠르고 압도적인 페이지 로드 속도를 제공합니다 [30, 32, 34]. 미리 렌더링된 완벽한 HTML을 제공하므로 SEO 성능이 탁월하며, 대규모 트래픽에도 매우 저렴하고 효율적으로 확장할 수 있습니다 [31, 33, 35, 36].
* **단점**: 콘텐츠를 업데이트하려면 사이트 전체를 다시 빌드하고 배포해야 하므로 데이터가 쉽게 구식이 될 수 있습니다 [33, 37]. 자주 변경되는 실시간 데이터나 사용자별 맞춤 콘텐츠를 제공하는 데는 한계가 있습니다 [33, 37].
* **적합한 사용 사례**: 콘텐츠 변동이 적고 방문자 모두에게 동일한 정보를 제공하는 마케팅 랜딩 페이지, 블로그, 기술 문서 사이트 등에 가장 완벽한 방식입니다 [31, 38].
## 🔗 Knowledge Connections
- **Related Topics:** [[Hydration|Hydration]], Single-Page Application (SPA), Incremental Static Regeneration (ISR), Time to Interactive (TTI), [[First Contentful Paint (FCP)|First Contentful Paint (FCP]]
- **Projects/Contexts:** [[Next.js|Next.js]], Nuxt, SvelteKit 등은 프로젝트 내에서 페이지 단위로 SSR, SSG, CSR 전략을 혼합(Hybrid)하여 사용할 수 있도록 지원하는 대표적인 프레임워크입니다 [39-41].
- **Contradictions/Notes:** 소스에 관련 정보가 부족합니다. (제공된 소스들 간에 CSR, SSR, SSG의 정의나 성능적 장단점 평가에 있어 상충하거나 모순되는 내용은 확인되지 않습니다.)
---
*Last updated: 2026-04-25*
@@ -1,27 +0,0 @@
# [[CSS Animations|CSS Animations]]
## 📌 Brief Summary
CSS 애니메이션은 UI/UX에서 사용자와 시스템 간의 상호작용을 강화하고 시각적 피드백을 제공하며, 시스템 상태나 계층 구조를 명확히 하는 데 사용되는 기술이다 [1, 2]. 단순한 시각적 장식이 아닌 인지 부하를 줄이고 사용성을 높이는 기능적 목적을 가지며 [2-4], 실무적으로는 브라우저의 리플로우(Reflow)와 리페인트(Repaint)를 최소화하여 60FPS의 렌더링 성능을 유지하고 유지보수가 용이하도록 설계되어야 한다 [5, 6].
## 📖 Core Content
* **애니메이션의 기능적 역할 및 UX 원칙**
애니메이션은 단순히 화면을 꾸미는 것이 아니라, 사용자에게 즉각적인 피드백을 주고 주의를 유도하며 원인과 결과의 관계를 설명하는 기능적 도구이다 [1, 2, 4]. 호버(Hover) 효과, 버튼 클릭 시의 마이크로 인터랙션, 로딩 상태 진행 표시, 부드러운 화면 상태 전환 등에 주로 활용된다 [7-10]. 애니메이션의 지속 시간은 사용자 대기 시간을 줄이기 위해 200ms에서 500ms 사이로 짧게 유지하는 것이 좋으며, 기계적인 선형 움직임 대신 `ease-in-out`과 같은 이징(Easing) 함수를 활용해 물리 법칙에 기반한 자연스러운 움직임을 설계해야 한다 [11-14].
* **성능 저하를 유발하는 안티 패턴 ([[Reflow & Repaint|Reflow & Repaint]])**
프론트엔드 실전 설계에서 애니메이션 성능은 변경되는 CSS 속성에 크게 좌우된다 [15, 16]. `width`, `height`, `margin`, `padding`, `top`, `left` 등의 레이아웃 속성을 애니메이션 처리하면 브라우저의 리플로우(Reflow)와 리페인트(Repaint)가 지속해서 발생하여 애니메이션이 끊기는 현상(Jank)이 발생한다 [5, 6, 15, 17]. 또한 `box-shadow`, `filter`, `border-radius` 및 크고 복잡한 배경 이미지의 애니메이션은 렌더링 자원 소모가 크기 때문에 주의가 필요하다 [16, 18]. 동시에 너무 많은 요소를 애니메이션하거나 불필요한 무한 루프(`infinite`)를 적용하는 것도 브라우저 성능을 크게 저하하는 원인이 된다 [19, 20].
* **유지보수 가능하고 확장성 있는 성능 최적화 전략**
부드럽고 렌더링 비용이 적은 애니메이션을 구현하기 위해서는 레이아웃에 영향을 주지 않는 `transform` (예: `translateZ()`, `scale()`)과 `opacity` 속성을 적극 활용해야 한다 [16, 21-23]. 이러한 속성들은 브라우저 렌더링 파이프라인에서 레이아웃과 페인트 단계를 건너뛰고 컴포지팅(Compositing) 단계만 거치게 되며, GPU 하드웨어 가속을 받아 모바일 기기에서도 뛰어난 성능을 보장한다 [16, 23, 24].
또한 `position: absolute``position: fixed` 요소에 애니메이션을 적용하면 DOM 트리의 다른 요소에 미치는 리플로우 영향을 차단할 수 있다 [24-26]. 애니메이션이 확정된 요소에는 `will-change` 속성을 부여해 브라우저가 최적화를 미리 준비하도록 힌트를 줄 수 있으나, 과도하게 사용할 경우 오히려 성능을 저하시키므로 최소화하여 사용해야 한다 [27, 28].
* **접근성과 실무 환경에서의 제어**
보이지 않는 요소의 무한 루프 애니메이션은 시스템 리소스를 고갈시키므로, `animation-play-[[State|State]]`를 사용해 화면 이탈 시 애니메이션을 일시 정지시키는 제어가 필요하다 [5, 20]. 아울러, 과도한 모션은 일부 사용자에게 어지러움을 유발할 수 있으므로 웹 콘텐츠 접근성 지침(WCAG)에 따라 `prefers-reduced-motion` 미디어 쿼리를 활용해 애니메이션을 선택적으로 줄이거나 제거할 수 있는 접근성 장치를 반드시 마련해야 한다 [11, 29, 30].
## 🔗 Knowledge Connections
- **Related Topics:** [[Reflow and Repaint|Reflow and Repaint]], Hardware Acceleration (GPU), Micro-interactions, [[Accessibility|Accessibility]] (prefers-reduced-motion)
- **Projects/Contexts:** [[Large Frontend Projects|Large Frontend Projects]], [[Performance Optimization|Performance Optimization]]
- **Contradictions/Notes:** 무한 루프 애니메이션과 화려한 모션은 인터페이스에 활력을 줄 수 있지만 시스템 리소스를 크게 소모하며, 전정기관 장애가 있는 사용자에게 위험할 수 있습니다 [11, 20]. 따라서 실무 환경에서는 애니메이션 적용을 필수적인 기능과 마이크로 인터랙션으로 제한하고, 화면에서 벗어났을 때 정지시키거나(`animation-play-state`) 사용자의 환경 설정에 따라 모션을 줄이는(`prefers-reduced-motion`) 방어적 설계가 동반되어야 합니다 [20, 29, 30].
---
*Last updated: 2026-04-26*
@@ -1,26 +0,0 @@
# [[CSS Architecture|CSS Architecture]]
## 📌 Brief Summary
CSS 아키텍처는 과거의 단순한 시각적 장식 계층에서 벗어나, 대규모 프론트엔드 프로젝트의 확장성과 유지보수성을 보장하기 위한 엄격한 엔지니어링 시스템입니다 [1]. 애플리케이션이 복잡해짐에 따라 흔히 발생하는 전역(Global) 네임스페이스 충돌과 'CSS 비대화(Bloat)' 같은 기술적 부채를 방지하는 것을 핵심 목적으로 합니다 [1, 2]. 현대의 CSS 설계는 BEM과 같은 수동적인 네이밍 규칙에서 출발하여, [[CSS Modules|CSS Modules]], [[Tailwind CSS|Tailwind CSS]]와 같이 스코프(Scope)를 격리하고 모듈화를 강제하는 자동화 및 유틸리티 기반 접근법으로 진화했습니다 [3-5].
## 📖 Core Content
현대의 프론트엔드 개발에서 CSS 설계는 "예쁘게" 만드는 것을 넘어, 여러 팀이 협업하고 프로젝트가 커져도 안정적으로 코드를 유지보수할 수 있는 구조를 구축하는 데 중점을 둡니다 [1, 2]. 이를 달성하기 위해 실무에서는 다음과 같은 구조 설계 방식과 전략을 활용합니다.
* **[[BEM (Block Element Modifier)|BEM (Block Element Modifier]] 구조:**
BEM은 UI를 독립적이고 재사용 가능한 '블록(Block)', 블록에 종속된 '요소(Element)', 그리고 상태나 모양을 변경하는 '수식어(Modifier)'로 나누어 명명하는 CSS 방법론입니다 [3, 6-8]. 선택자를 평면적(Flat)으로 유지하여 깊은 DOM 중첩으로 인한 성능 저하를 막고, 스타일이 어느 컴포넌트에 속하는지 명확하게 알려줍니다 [9, 10]. 하지만 규칙을 사람이 직접 지켜야 하므로 프로젝트가 커질수록 실수가 발생하기 쉽고, 사용하지 않는 코드를 자동으로 제거(Dead code elimination)하기 어렵다는 단점이 있습니다 [11].
* **CSS Modules를 통한 자동화된 캡슐화:**
CSS Modules는 일반적인 CSS(또는 [[SCSS|SCSS]]) 문법을 작성하되, 빌드 시점에 고유한 해시값이 포함된 클래스 이름을 자동으로 생성하여 로컬 스코프(Local Scoping)를 보장하는 방식입니다 [12-14]. BEM이 가진 수동 네이밍의 한계를 해결하고 컴포넌트 간 스타일 충돌을 원천 차단하므로, 복잡한 애니메이션이나 세밀한 CSS 제어가 필요한 프로젝트에서 선호됩니다 [15-17].
* **Tailwind CSS와 유틸리티 우선(Utility-First) 전략:**
Tailwind는 `flex`, `pt-4`, `text-gray-500`과 같은 단일 목적의 작은 유틸리티 클래스를 HTML이나 JSX에 직접 조합하여 UI를 구성합니다 [18, 19]. 설정 파일에 디자인 토큰을 정의해두기 때문에 임의의 색상이나 간격이 무분별하게 늘어나는 것을 막아 시각적 일관성을 유지할 수 있습니다 [18, 20]. 사용된 클래스만 최종 빌드에 포함되므로 대규모 프로젝트에서도 CSS 파일의 크기가 일정 수준에서 더 이상 늘어나지 않는다는 강력한 이점이 있습니다 [18, 19].
* **실무에서의 CSS 관리 및 아키텍처 통합 전략:**
최근의 엔터프라이즈 팀들은 단일 기술에 얽매이지 않고, 레이아웃과 간격 배치 등 속도와 일관성이 중요한 부분에는 Tailwind CSS를 사용하고, 고도로 복잡한 컴포넌트 스타일링에는 CSS Modules나 SCSS를 결합하는 하이브리드 접근법을 취하기도 합니다 [21-23]. 또한, 폰트 크기나 색상 등을 플랫폼에 종속되지 않는 '디자인 토큰([[Design Tokens|Design Tokens]])'으로 추상화하여 관리함으로써 디자인 시스템과 CSS 아키텍처를 하나로 통합합니다 [24, 25].
## 🔗 Knowledge Connections
- **Related Topics:** [[BEM (Block Element Modifier)|BEM (Block Element Modifier]], CSS Modules, Tailwind CSS, [[Design Tokens|Design Tokens]], [[Feature-Sliced Design (FSD)|Feature-Sliced Design (FSD]]
- **Projects/Contexts:** 대규모 엔터프라이즈 프론트엔드 프로젝트, 컴포넌트 기반 아키텍처 (React, [[Next.js|Next.js]]), [[디자인 시스템 구축|디자인 시스템 구축]]
- **Contradictions/Notes:**
- CSS 설계에서 BEM은 이름 충돌을 방지하는 훌륭한 수단으로 소개되지만 [3], 최근 모던 프론트엔드 생태계에서는 CSS Modules가 클래스 이름의 격리를 자동으로 해결해주기 때문에 BEM의 수동적인 네이밍 컨벤션은 더 이상 필수적이지 않다는 시각이 존재합니다 [17, 26, 27].
- Tailwind CSS는 빠른 개발 속도와 일관된 디자인 시스템을 장점으로 내세우지만 [19], 동시에 HTML 마크업이 지나치게 길어지며 과거의 '인라인 스타일(Inline CSS)'로 퇴보하는 것 같아 추상화 방식에 동의하지 않는다는 개발자들의 비판적인 의견도 분명하게 대립하고 있습니다 [20, 28, 29].
---
*Last updated: 2026-04-26*
@@ -1,25 +0,0 @@
# [[CSS Container Queries|CSS Container Queries]]
## 📌 Brief Summary
CSS [[Container Queries|Container Queries]](컨테이너 쿼리)는 전체 뷰포트(브라우저 창)의 크기가 아닌, 컴포넌트가 속한 부모 컨테이너의 가용 공간을 기준으로 스타일과 레이아웃을 조정하는 강력한 CSS 기능입니다 [1-3]. 이는 좁은 사이드바에 위치한 카드와 넓은 메인 화면에 위치한 카드가 동일한 뷰포트 너비 환경에서도 각기 다른 형태를 가져야 하는 기존 미디어 쿼리(Media Queries)의 근본적인 한계를 해결해 줍니다 [1, 4]. 결과적으로 웹 디자인의 패러다임을 페이지 수준에서 컴포넌트 수준으로 전환시키며, 2026년 기준 모듈식 반응형 디자인 및 디자인 시스템 구축을 위한 필수적인 표준 기술로 자리 잡았습니다 [1, 5, 6].
## 📖 Core Content
* **작동 원리 및 문법 적용**
컨테이너 쿼리를 사용하려면 부모 컨테이너에 `container-type: inline-size;` 속성을 선언하여 컨텍스트를 활성화해야 합니다 [4, 7]. 이후 `@container (min-width: 600px)`와 같은 문법을 작성하면, 전체 화면의 크기와 상관없이 해당 컨테이너가 지정된 임계값에 도달했을 때 자식 요소의 스타일(예: 1열에서 2열 레이아웃으로 변경)이 적용됩니다 [2, 7].
* **가변 타이포그래피([[Fluid Typography|Fluid Typography]])와의 결합**
컨테이너 쿼리는 크기 기반 레이아웃뿐만 아니라 텍스트 크기 조정에도 활용됩니다. `cqw``cqi`와 같은 전용 단위(컨테이너 인라인 너비의 1%를 의미)를 `clamp()` 함수 등과 함께 사용하면, 뷰포트가 아닌 컨테이너 크기에 반응하여 유동적으로 조절되는 가변 타이포그래피를 구현할 수 있습니다 [8-10].
* **모듈식 아키텍처 및 유지보수성 극대화**
컨테이너 쿼리를 도입하면 개별 컴포넌트가 자신이 배치된 환경(Context)을 자체적으로 인지하고 구조를 조정하는 완전한 자립형(Self-contained) 모듈이 됩니다 [1, 4]. 따라서 동일한 컴포넌트를 애플리케이션의 어느 위치에 재사용하더라도 깨짐 없이 일관되게 동작하며, 이는 독립적인 UI 단위 구성을 지향하는 현대의 디자인 시스템(DesignSystems) 철학과 완벽하게 부합합니다 [1, 4, 11, 12].
* **실무 활용 및 2026년 표준 관행**
과거에는 실험적인 고급 기술이었으나 2024년 이후 모든 최신 브라우저에서 온전히 지원되며 프로덕션 환경에서 안전하게 사용할 수 있습니다 [1]. 2026년 현재, 이커머스의 다중 패널 레이아웃이나 공간 제약이 많은 [[SaaS|SaaS]] 대시보드에서 데이터 테이블을 카드 스택으로 유연하게 변환하는 등, 자바스크립트에 의존하지 않고도 컴포넌트 수준의 복잡한 반응형 동작을 처리하는 기본 관행(Default practice)이 되었습니다 [5, 7, 13-15].
## 🔗 Knowledge Connections
- **Related Topics:** [[미디어 쿼리 (Media Queries)|미디어 쿼리 (Media Queries]], 반응형 웹 디자인 (Responsive Web Design), [[디자인 시스템 (Design Systems)|디자인 시스템 (Design Systems]], [[모듈식 컴포넌트 (Modular Components)|모듈식 컴포넌트 (Modular Components]]
- **Projects/Contexts:** [[SaaS 대시보드 및 이커머스 레이아웃 구축|SaaS 대시보드 및 이커머스 레이아웃 구축]], [[가변 타이포그래피 (Fluid Typography)|가변 타이포그래피 (Fluid Typography]]
- **Contradictions/Notes:** 컨테이너 쿼리는 미디어 쿼리를 완전히 대체하는 것이 아닙니다. 미디어 쿼리가 디바이스나 뷰포트 너비에 대응하는 전역적(페이지 수준) 레이아웃을 관리한다면, 컨테이너 쿼리는 "뷰포트 중심에서 컴포넌트 중심"으로 관점을 전환하여 개별 요소 내부의 지역적인 공간 적응을 전담함으로써 상호 보완적으로 작동합니다 [1, 3, 6].
---
*Last updated: 2026-04-26*
@@ -1,31 +0,0 @@
# [[CSS Grid 및 Flexbox|CSS Grid 및 Flexbox]]
## 📌Brief 신Summary
CSS [[Flexbox|Flexbox]]와 [[CSS Grid|CSS Grid]]는 웹 페이지의 요소들을 배치하고 정렬하기 위해 도입된 최신 CSS 레이아웃 모듈입니다 [1-3]. Flexbox는 행(Row)이나 열(Column) 중 하나의 방향으로 요소를 배치하는 1차원 레이아웃에 특화되어 있으며, CSS Grid는 행과 열을 동시에 제어하는 2차원 레이아웃 시스템입니다 [4-6]. 이 두 기술은 과거의 float이나 복잡한 위치 지정(positioning) 방식을 대체하여, 예측 가능하고 유지보수가 용이한 반응형 디자인을 구축하는 핵심 도구로 사용됩니다 [7-9].
## 📖 Core Content
**1. Flexbox (1차원 레이아웃 및 컴포넌트 정렬)**
* **목적 및 특징:** Flexbox는 단일 차원(행 또는 열)에서 항목을 정렬하고 간격을 분배하는 데 최적화되어 있습니다 [4, 9, 10]. 주로 내비게이션 바, 폼 필드, 카드 컴포넌트 내의 텍스트와 이미지 정렬 등 소규모 레이아웃에 적합합니다 [3, 11, 12].
* **동작 원리 (Content-out):** Flexbox는 '콘텐츠 중심(Content-out)'으로 동작합니다. 요소들의 내부 콘텐츠 크기에 따라 항목이 커지거나(`flex-grow`) 줄어들며(`flex-shrink`), 가용 공간을 유연하게 채웁니다 [1, 13-16]. 화면 크기가 줄어들면 `flex-wrap` 속성을 통해 자연스럽게 다음 줄로 넘어가게 할 수 있습니다 [17, 18].
**2. CSS Grid (2차원 레이아웃 및 페이지 구조화)**
* **목적 및 특징:** CSS Grid는 행(Row)과 열(Column)을 동시에 다룰 수 있는 가장 강력한 2차원 레이아웃 도구입니다 [5, 6, 19]. 전체 페이지 구조, 데이터 대시보드, 복잡한 이미지 갤러리 등 정밀한 배치가 필요한 대규모 레이아웃에 적합합니다 [20-22].
* **동작 원리 (Layout-in):** CSS Grid는 '레이아웃 중심(Layout-in)'으로 동작합니다. 먼저 그리드 구조(행과 열의 틀)를 정의한 뒤, 그 틀 안의 특정 셀이나 영역에 콘텐츠를 배치합니다 [16, 23]. 아이템들이 여러 행과 열에 걸쳐 병합(spanning)되거나 겹치도록 정밀하게 제어할 수 있습니다 [22, 24, 25].
**3. 반응형 디자인에서의 역할**
* 두 기술 모두 고정된 픽셀 폭 대신 유연한 유닛과 논리를 사용하여 수많은 미디어 쿼리(Media Queries)를 줄이는 데 기여합니다 [26, 27].
* 예를 들어, CSS Grid의 `auto-fit` 속성과 `minmax()` 함수를 결합하면 화면의 가용 공간에 맞춰 열의 개수를 동적으로 자동 조절하는 반응형 그리드를 손쉽게 구현할 수 있습니다 [28-31].
**4. 실무 레이아웃 통합 전략 (Grid + Flexbox)**
* 대규모 프론트엔드 프로젝트에서 가장 권장되는 아키텍처 원칙은 **"레이아웃에는 CSS Grid를, 정렬에는 Flexbox를 사용하라(Grid is for layout; Flexbox is for [[Alignment|Alignment]])"**는 것입니다 [32-34].
* CSS Grid를 사용하여 헤더, 푸터, 사이드바, 메인 콘텐츠 영역 등 애플리케이션의 '주요 레이아웃 스타일(Major layout style)'을 구축합니다 [34, 35].
* 그런 다음 개별 그리드 셀 내부에 들어가는 버튼 그룹, 아이콘, 텍스트 등의 요소들을 정렬할 때는 Flexbox를 활용합니다 [35, 36].
* 이러한 하이브리드 접근 방식은 불필요한 래퍼(Wrapper) 요소의 중첩을 줄여 DOM 구조를 가볍게 만들고, 브라우저 렌더링 성능과 코드의 유지보수성을 크게 향상시킵니다 [35, 37-39].
## 🔗 Knowledge Connections
- **Related Topics:** [[반응형 디자인|반응형 디자인]], CSS 아키텍처, [[BEM|BEM]]
- **Projects/Contexts:** 대규모 프론트엔드 아키텍처 최적화, 컴포넌트 기반 UI/UX 설계
- **Contradictions/Notes:** Flexbox와 CSS Grid는 서로를 대체하는 기술이 아닙니다 [40, 41]. 오히려 Flexbox는 1차원 정렬(예: 한 줄 또는 한 열의 아이템 배치)에 직관적이고 적합하며, CSS Grid는 2차원의 복잡한 구조 배치에 강점을 지니므로 두 기술을 상호 보완적으로 함께 사용해야 완벽한 레이아웃 시스템을 설계할 수 있다고 여러 소스에서 강조합니다 [8, 36, 39, 40].
---
*Last updated: 2026-04-26*
@@ -1,29 +0,0 @@
# [[CSS Grid|CSS Grid]]
## 📌 Brief Summary
CSS Grid는 행(Row)과 열(Column)을 동시에 다루어 복잡하고 체계적인 웹 페이지 구조를 설계할 수 있도록 돕는 2차원 레이아웃 시스템입니다 [1, 2]. [[Flexbox|Flexbox]]와 달리 레이아웃 구조를 먼저 정의하고 요소를 배치하는 '레이아웃 우선(layout in)' 방식을 취하며, 대규모 페이지 레이아웃이나 대시보드, 갤러리 등 정밀한 배치가 필요한 곳에 가장 적합합니다 [3-5].
## 📖 Core Content
* **2차원 레이아웃 제어:**
* 1차원(행 또는 열)으로만 작동하는 Flexbox와 다르게, CSS Grid는 가로와 세로 두 방향의 레이아웃을 동시에 제어할 수 있습니다 [2, 6].
* 복잡한 중첩 컨테이너를 생성할 필요 없이 깔끔한 마크업으로 복잡한 디자인(예: 헤더, 푸터, 사이드바, 메인 콘텐츠 배치)을 쉽게 구현할 수 있습니다 [7, 8].
* **정밀한 배치 및 오버랩(Overlap):**
* `grid-template-columns`, `grid-template-rows`, `grid-template-areas` 등의 속성을 통해 아이템을 원하는 위치에 정확히 배치할 수 있습니다 [9, 10].
* `grid-column``grid-row` 속성을 활용해 복잡한 마진이나 절대 위치 지정(Absolute positioning) 없이도 요소들을 겹치게 만들 수 있어 시각적인 계층을 표현하는 데 유리합니다 [11, 12].
* **강력한 반응형 설계 기능:**
* 여백 제어용 `gap`(`grid-gap`) 속성을 네이티브로 지원하므로 margin과 관련된 부작용을 방지합니다 [6, 12].
* `fr`(분수) 단위와 `minmax()` 함수, 그리고 `repeat(auto-fit, ...)` 같은 기능을 결합하여, 미디어 쿼리에 크게 의존하지 않고도 가용 공간에 따라 트랙 수가 동적으로 변하는 유연한 반응형 레이아웃을 구현할 수 있습니다 [13-17].
* **다른 CSS 기능과의 상호작용:**
* **절대 위치 지정:** Grid 컨테이너에 `position: relative`를 주면 내부의 절대 위치(`position: absolute`) 요소가 전체 그리드 또는 할당된 그리드 영역(Grid Area)을 기준으로 정밀하게 배치될 수 있습니다 [18-20].
* **`display: contents` 활용:** Grid 항목의 래퍼(Wrapper) 요소에 `display: contents`를 적용하면, 해당 래퍼의 박스는 사라지고 내부 자식 요소들이 직접 Grid 시스템의 항목으로 편입되어 그리드의 정렬 규칙을 따르게 됩니다 [21-23].
* **실무 유지보수를 위한 설계 전략 (Flexbox와의 조합):**
* 모던 프론트엔드 아키텍처에서는 CSS Grid와 Flexbox 중 하나만 선택하는 것이 아니라, 목적에 맞게 두 가지를 혼용하는 것이 핵심입니다 [24, 25].
* 전체 페이지의 구조(Major layout)나 대규모 뼈대는 2차원인 **CSS Grid**로 잡고, 해당 셀 내부에 들어가는 UI 컴포넌트들의 세부적인 정렬은 1차원인 **Flexbox**로 처리하는 것이 유지보수성 높은 코드를 작성하는 모범 사례입니다 [26-29].
## 🔗 Knowledge Connections
- **Related Topics:** [[Flexbox|Flexbox]], [[반응형 디자인|반응형 디자인]]
- **Projects/Contexts:** 유지보수 가능한 CSS 레이아웃 설계, 웹 페이지 및 대시보드 구조화
- **Contradictions/Notes:** Flexbox는 콘텐츠의 크기를 기반으로 공간을 분배하는 '콘텐츠 우선(content out)' 방식으로 동작하지만, CSS Grid는 정의된 레이아웃의 형태에 요소를 끼워 맞추는 '레이아웃 우선(layout in)' 방식을 취합니다 [5, 30]. CSS Grid가 더 복잡한 기능을 제공하지만 단순한 1차원 정렬(행, 열 내에서의 아이템 정렬)에 사용하기에는 과도한 설정(overkill)이 될 수 있으므로 상황에 맞게 Flexbox와 구별해 사용해야 합니다 [6, 27, 31].
---
*Last updated: 2026-04-26*
@@ -1,19 +0,0 @@
# [[CSS Media Queries|CSS Media Queries]]
## 📌 Brief Summary
CSS Media Queries(미디어 쿼리)는 뷰포트 너비, 화면 해상도, 방향 등의 특정 조건에 따라 각기 다른 CSS 스타일을 적용할 수 있게 해주는 규칙이다 [1, 2]. 이는 반응형 웹 디자인의 논리적 토대를 형성하며, 다양한 디바이스에 맞춰 단일 코드베이스로 레이아웃을 유연하게 조정할 수 있도록 돕는다 [1-3]. 또한, 특정 조건에서만 필요한 스타일을 분리하여 브라우저의 초기 렌더링 차단 현상을 방지하는 등 웹 성능 최적화에도 필수적인 역할을 한다 [4, 5].
## 📖 Core Content
- **반응형 디자인의 논리적 기반:** 미디어 쿼리는 뷰포트 너비뿐만 아니라 고해상도 디스플레이, 다크/라이트 모드, 가로/세로 화면 방향 등의 조건에 반응하여 각기 다른 CSS 규칙을 적용할 수 있게 해준다 [2, 6]. 이를 통해 모바일용과 데스크톱용 페이지를 따로 만들 필요 없이 유기적으로 적응하는 레이아웃을 구성할 수 있다 [1, 2].
- **모바일 우선 설계 ([[Mobile-First Approach|Mobile-First Approach]]):** 미디어 쿼리 작성 시 가장 작은 화면(모바일)을 위한 기본 스타일을 먼저 정의한 후, `min-width` 쿼리를 사용해 화면이 커짐에 따라 점진적으로 복잡한 레이아웃이나 요소를 추가하는 것이 권장된다 [7-9]. 이 방식은 불필요한 스타일 덮어쓰기를 방지하여 코드를 논리적이고 유지보수하기 쉽게 만들어준다 [9].
- **중단점(Breakpoints) 설정 원칙:** 특정 디바이스의 해상도 규격에 맞춰 중단점을 정하기보다는, 화면을 줄이거나 늘릴 때 콘텐츠의 레이아웃이 깨지기 시작하는 지점을 기준으로 설정해야 한다 [10]. 실무에서는 통상적으로 모바일(480px 이하), 태블릿(481~1024px), 데스크톱(1200px 이상) 등과 같은 구간을 활용한다 [2, 6, 10].
- **렌더링 성능 최적화 (Optimizing Render [[Blocking|Blocking]]):** 브라우저는 CSS 파싱을 완료하기 전까지 화면 렌더링을 차단하지만, 미디어 쿼리를 활용하면 이 문제를 완화할 수 있다 [4]. HTML `<link>` 태그에 `media` 속성을 명시하여 인쇄용(print)과 같이 당장 필요하지 않은 스타일 시트를 분리하면, 브라우저가 해당 파일을 다운로드하더라도 렌더링 과정을 차단하지 않아 페이지 로딩 속도를 향상시킬 수 있다 [4, 5, 11].
- **뷰포트 한계와 컴포넌트 중심 설계로의 진화:** 뷰포트 기반 미디어 쿼리는 화면 전체 크기에 반응할 뿐, 컴포넌트가 실제로 속해 있는 부모 컨테이너의 가용 공간을 인식하지 못하는 근본적인 한계를 지닌다 [12]. 따라서 디자인 시스템이나 모듈화된 설계를 위해, 2026년 현재는 부모 컨테이너의 크기에 맞춰 컴포넌트가 스스로 형태를 변경하는 컨테이너 쿼리([[Container Queries|Container Queries]])와 미디어 쿼리를 병행해서 사용하는 것이 표준으로 자리 잡았다 [12-14].
## 🔗 Knowledge Connections
- **Related Topics:** [[반응형 디자인|반응형 디자인]], Container Queries, Mobile-First Design, [[CSS Performance Optimization|CSS Performance Optimization]]
- **Projects/Contexts:** [[실무에서 CSS 관리하는 방법|실무에서 CSS 관리하는 방법]], [[디자인 시스템 개념|디자인 시스템 개념]]
- **Contradictions/Notes:** 소스에서는 뷰포트 기반의 미디어 쿼리만으로는 완벽한 재사용 컴포넌트를 만드는 데 제약이 있다고 지적한다. 사이드바나 모달 등 다양한 컨텍스트(공간)에 독립적으로 반응해야 하는 컴포넌트를 설계할 때는 미디어 쿼리보다 컨테이너 쿼리를 사용하는 것이 더 적합하며, 이는 최근 반응형 디자인의 패러다임이 페이지 수준에서 컴포넌트 수준으로 이동했음을 보여준다 [12, 14-16].
---
*Last updated: 2026-04-26*
@@ -1,30 +0,0 @@
# [[CSS Modules|CSS Modules]]
## 📌 Brief Summary
CSS Modules는 표준 CSS 문법을 사용하면서도 빌드 단계에서 클래스명을 고유하게 변환하여 컴포넌트 단위로 스타일을 자동으로 스코핑(scoping)하는 CSS 아키텍처 접근법입니다 [1-3]. 전역 네임스페이스 충돌을 방지하기 위해 BEM과 같은 수동 규칙에 의존하는 대신, 도구를 통해 고유한 해시 클래스명을 생성함으로써 유지보수성을 극대화합니다 [4, 5]. 런타임 오버헤드가 없는 정적 CSS를 생성하므로 성능이 뛰어나며, React 및 [[Next.js|Next.js]]와 같은 최신 프레임워크 환경에서 전역 오염 없이 안전하게 UI를 구축할 수 있게 해줍니다 [6-8].
## 📖 Core Content
* **동작 방식 및 특징:**
CSS Modules를 사용하면 개발자는 익숙한 표준 CSS 문법을 그대로 작성할 수 있습니다 [6, 9]. 작성된 CSS 파일(`.module.css`)을 [[JavaScript|JavaScript]] 컴포넌트에 임포트하면, 빌드 도구가 `.button`과 같은 클래스명을 `Button_button__x9KdL`과 같은 고유한 식별자로 자동 변환합니다 [3, 9]. 또한, `composes` 기능을 통해 기존 스타일을 쉽게 확장할 수 있으며 [1], Sass([[SCSS|SCSS]])나 PostCSS와 같은 기존 CSS 도구와도 완벽하게 통합됩니다 [1, 10].
* **장점:**
* **완벽한 스코핑 및 충돌 방지:** 클래스명이 자동으로 컴포넌트에 스코핑되므로, 스타일이 의도치 않게 다른 곳에 영향을 미치는 전역 충돌(global namespace collision) 문제를 원천적으로 차단합니다 [5, 6, 9, 11].
* **제로 런타임 오버헤드 (Zero Runtime Overhead):** 스타일이 빌드 타임에 처리되어 정적 CSS로 출력되므로, 런타임에 스타일을 파싱하는 [[CSS-in-JS|CSS-in-JS]] 방식과 달리 브라우저 성능에 악영향을 주지 않으며 브라우저 캐싱을 최대한 활용할 수 있습니다 [6, 7, 12].
* **기존 CSS 생태계 및 유연성 활용:** 복잡한 애니메이션, 미디어 쿼리, 가상 요소(pseudo-elements) 및 복잡한 선택자 등 CSS의 모든 기능을 제한 없이 자연스럽게 사용할 수 있습니다 [7, 9]. 특정 프레임워크에 종속되지 않습니다 [7].
* **개발자 경험 향상:** TypeScript와 결합하여 모듈 클래스명에 대한 타이핑을 생성함으로써 오타를 빌드 타임에 잡아낼 수 있습니다 [13].
* **단점 및 한계:**
* **파일 전환 (Context Switching):** 스타일을 수정할 때 JavaScript/JSX 파일과 `.module.css` 파일을 번갈아 가며 작업해야 하는 번거로움이 있습니다 [7].
* **동적 스타일링의 어려움:** CSS-in-JS와 달리 CSS와 JavaScript 간에 데이터를 공유하거나 컴포넌트 상태(Props)에 따른 동적인 스타일을 직접 부여하는 과정이 까다로우며, 이를 위해 조건부 문자열 연결(string concatenation) 작업이 필요합니다 [1, 7, 10].
* **네이밍 피로 (Naming Fatigue):** 유틸리티 클래스를 제공하는 [[Tailwind CSS|Tailwind CSS]]와 달리 개발자가 여전히 요소마다 의미 있는 클래스 이름을 고민하고 지어주어야 합니다 [14].
* **실무 활용 전략:**
CSS Modules는 탄탄한 CSS 역량을 갖춘 팀이나, 복잡한 애니메이션 및 세밀한 CSS 제어가 필요한 프로젝트에 가장 적합합니다 [14]. 특히 2025년 기준 [[Next.js App Router|Next.js App Router]]와 같은 [[React Server Components|React Server Components]](RSC) 환경에서는 런타임 CSS-in-JS 라이브러리의 호환성 문제로 인해 Tailwind CSS나 CSS Modules를 사용하는 것이 강력히 권장됩니다 [8, 15]. 대규모 프로젝트의 실무에서는 레이아웃과 간격에는 빠르고 일관된 Tailwind CSS를 사용하고, 복잡한 커스텀 로직이나 애니메이션이 필요한 컴포넌트 스타일에는 CSS Modules를 사용하는 방식으로 두 기술의 장점을 결합한 하이브리드 아키텍처를 채택하기도 합니다 [16-18].
## 🔗 Knowledge Connections
- **Related Topics:** [[BEM|BEM]], Tailwind CSS, CSS-in-JS, [[SCSS|SCSS]]
- **Projects/Contexts:** [[컴포넌트 기반 아키텍처|컴포넌트 기반 아키텍처]], React Server Components, [[Next.js App Router|Next.js App Router]]
- **Contradictions/Notes:** 소스 문헌들은 BEM이 개발자의 수동적인 명명 규칙 준수에 의존해 휴먼 에러가 발생하기 쉬운 반면, CSS Modules는 빌드 도구를 통해 "자동화된 캡슐화"를 제공하여 BEM이 풀고자 했던 문제를 더 깔끔하게 해결한다고 비교합니다 [4, 5, 11, 13]. 또한, Tailwind CSS는 클래스명을 짓는 수고와 파일 전환의 피로를 없애주지만 마크업 코드가 길어지고 자의적인 값이 쌓일 수 있는 반면, CSS Modules는 깔끔한 HTML을 유지하지만 파일 전환과 네이밍 피로가 존재한다는 트레이드오프 관계를 가집니다 [7, 14, 19, 20].
---
*Last updated: 2026-04-26*
@@ -1,35 +0,0 @@
# [[CSS Performance Optimization|CSS Performance Optimization]]
## 📌 Brief Summary
CSS 성능 최적화는 브라우저의 렌더링 경로에서 병목 현상을 유발하는 렌더링 차단 요소를 줄이고, 연산 비용이 높은 리플로우(Reflow)와 리페인트(Repaint)를 최소화하여 웹페이지의 반응성과 로딩 속도를 향상시키는 과정입니다 [1-4]. "예쁘게" 만드는 것을 넘어 "유지보수 가능하게" CSS를 설계하려면 불필요한 스타일 제거, 애니메이션의 GPU 가속 활용은 물론, [[CSS Modules|CSS Modules]]나 [[Tailwind CSS|Tailwind CSS]]처럼 런타임 오버헤드가 적은 도구를 선택하여 번들 크기와 아키텍처 성능을 동시에 관리하는 실무적 접근이 필수적입니다 [5-8].
## 📖 Core Content
* **렌더링 차단 방지 및 파일 최적화**
* 브라우저가 CSS를 다운로드하고 [[CSSOM(CSS Object Model)|CSSOM(CSS Object Model]]을 구축하기 전까지 페이지 렌더링이 차단됩니다 [2]. 이를 방지하기 위해 미디어 쿼리(media queries)를 활용하여 인쇄용이나 특정 화면 크기에만 필요한 스타일을 별도의 파일로 분리해야 합니다 [9, 10].
* 사용하지 않는 CSS(Dead code)를 제거하고, 사람이 읽기 위해 추가된 공백을 지우는 압축(Minify) 작업을 거쳐 파일 크기를 줄여야 합니다 [2, 11].
* `rel="preload"`를 사용하면 폰트, CSS 파일, 이미지 등 핵심 자산을 조기에 다운로드하여 사용자가 화면을 빠르게 볼 수 있도록 렌더링을 최적화할 수 있습니다 [12-14].
* **리플로우(Reflow)와 리페인트(Repaint) 최소화**
* 가시성이나 배경색 변경과 같은 시각적 변화는 **리페인트**를 발생시키며, 너비, 높이, 마진 등 요소의 기하학적 형태나 레이아웃이 변경되면 전체 또는 일부 페이지 레이아웃을 다시 계산해야 하는 **리플로우**가 발생해 심각한 성능 저하를 초래합니다 [4, 15].
* 리플로우 영향을 줄이려면 자바스크립트로 여러 인라인 스타일을 반복적으로 조작하지 말고, 미리 정의된 외부 클래스 하나를 조작하여 한 번의 리플로우만 발생하게 해야 합니다 [16, 17]. DOM 트리의 가장 하단(자식) 노드에서 클래스를 변경하는 것이 리플로우 범위를 최소화하는 데 효과적입니다 [18].
* **애니메이션 성능 최적화 전략**
* 애니메이션에 `width`, `height`, `margin` 등의 레이아웃 속성을 사용하면 지속적인 리플로우와 리페인트를 유발하여 화면이 끊기는(Janky) 현상이 발생합니다 [19]. 대신 레이아웃에 영향을 주지 않는 `transform``opacity` 속성을 사용하여 브라우저의 GPU 가속(Compositing)을 활용해야 합니다 [6, 20, 21].
* `box-shadow`, `filter`, `border-radius`와 같이 브라우저 연산 비용이 높은 속성을 사용한 애니메이션과, 무거운 배경 이미지 및 불필요한 무한 반복 루프 애니메이션을 피해야 합니다 [21-24].
* 자주 변경되는 요소에는 `will-change` 속성을 부여하여 브라우저가 사전에 렌더링 최적화를 준비하게 할 수 있지만, 너무 많은 요소에 남용하면 역효과가 나므로 주의가 필요합니다 [25, 26].
* **실무적 관점: 최신 CSS 아키텍처와 성능 비교**
* CSS 관리 방식을 선택할 때 런타임 성능과 번들 크기를 반드시 고려해야 합니다 [7]. 런타임 [[CSS-in-JS|CSS-in-JS]](예: [[styled-components|styled-components]], Emotion) 라이브러리는 자바스크립트 실행 중 CSS를 파싱하고 주입해야 하므로 런타임 오버헤드가 발생하고 파일 크기가 커져 성능이 떨어질 수 있습니다 [27-30].
* 반면 **Tailwind CSS**는 유틸리티 클래스를 사용하여 실제로 쓰인 스타일만 빌드에 포함시키므로 번들 크기를 극적으로 줄일 수 있으며(5~20kb), 런타임 비용이 발생하지 않습니다 [8, 31].
* **CSS Modules** 역시 빌드 시에 고유 클래스명을 정적으로 생성하므로 캡슐화(스코핑)를 보장하면서도 런타임 오버헤드가 없어 성능 친화적인 아키텍처를 구현할 수 있습니다 [5, 8, 32].
## 🔗 Knowledge Connections
- **Related Topics:** [[CSS 구조 설계 방식|CSS 구조 설계 방식]], BEM, CSS Modules, [[Tailwind vs 일반 CSS 비교|Tailwind vs 일반 CSS 비교]], 애니메이션 (transition / keyframes)
- **Projects/Contexts:** [[실무에서 CSS 관리하는 방법|실무에서 CSS 관리하는 방법]], [[대규모 프론트엔드 프로젝트 아키텍처|대규모 프론트엔드 프로젝트 아키텍처]]
- **Contradictions/Notes:**
- CSS-in-JS는 동적인 스타일링과 개발자 편의성을 제공하지만 성능(번들 크기 및 런타임 비용)에서는 CSS Modules나 Tailwind CSS에 비해 단점이 큽니다 [8, 27-29].
- 모바일이나 저사양 기기에서 애니메이션을 구현할 때는 시각적인 '부드러움(Smoothness)'을 고집하기보다는 CPU 자원을 아끼기 위해 의도적으로 픽셀 이동 단위를 조정하여 '속도(Speed)'를 챙기는 형태의 타협도 성능 최적화 방법으로 제안됩니다 [33].
---
*Last updated: 2026-04-26*
@@ -1,25 +0,0 @@
# [[CSS Variables|CSS Variables]]
## 📌 Brief Summary
CSS Variables(사용자 지정 속성, CSS custom properties)은 React 및 최신 프론트엔드 프로젝트에서 디자인 토큰을 관리하고 동적 테마를 구현하는 데 사용되는 핵심 기반 기술입니다. 이 기술은 애플리케이션 전반에 걸쳐 하드코딩된 스타일 값을 대체하여 디자인의 일관성을 유지하고, 라이트/다크 모드와 같은 테마 전환을 쉽게 만듭니다. 특히 [[Tailwind CSS v4|Tailwind CSS v4]]와 같은 최신 프레임워크나 styled-components와 같은 CSS-in-JS 환경에서 [[React Server Components|React Server Components]](RSC) 호환성 및 런타임 성능 최적화를 달성하기 위한 필수적인 해결책으로 채택되고 있습니다.
## 📖 Core Content
* **디자인 토큰과 동적 테마([[Dynamic Theming|Dynamic Theming]])의 핵심:**
CSS 변수는 색상, 타이포그래피, 간격 등의 디자인 토큰을 중앙 집중화하여 관리하는 단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]]) 역할을 합니다 [1, 2]. Style Dictionary와 같은 도구를 사용해 JSON 형식의 디자인 토큰을 CSS 변수(예: `--color-primary`)로 변환하고 이를 `:root` 레벨에 정의하면, [[JavaScript|JavaScript]]의 개입 없이도 기본 테마나 라이트/다크 모드를 동적으로 전환할 수 있습니다 [3-6].
* **[[Tailwind CSS|Tailwind CSS]] v4의 CSS 우선(CSS-first) 아키텍처:**
Tailwind CSS v4는 기존의 JavaScript 설정 파일(tailwind.config.js)을 제거하고 `@theme` 디렉티브를 사용하여 디자인 토큰을 기본 CSS 변수로 직접 노출합니다 [7-10]. 이를 통해 개발자는 JavaScript 구동 컨텍스트 업데이트 없이 런타임 테마 적용과 타입 안정성(Type Safety)을 확보할 수 있습니다 [10, 11]. 또한, 생성된 정규 CSS 변수는 인라인 스타일이나 임의의 값(arbitrary values)에서 참조할 수 있으며, JavaScript의 `getComputedStyle`을 통해서도 쉽게 접근이 가능합니다 [12-14].
* **styled-components 및 RSC 환경에서의 한계 극복:**
React [[Server Components|Server Components]](RSC) 환경에서는 [[React Context|React Context]]가 제공되지 않기 때문에, styled-components나 Emotion이 의존하던 `ThemeProvider`를 통한 동적 테마 주입이 작동하지 않습니다 [15-17]. 이를 해결하기 위해 styled-components v6.4+ 에서는 `createTheme` 함수를 도입하여 테마 객체의 모든 리프(leaf) 값을 CSS 변수 참조(`var(--prefix-path)`)로 변환합니다 [18]. 이 접근법을 사용하면 React 컨텍스트 없이도 클라이언트 컴포넌트와 RSC 모두에서 안정적으로 테마를 적용할 수 있습니다 [18].
* **컴포넌트 아키텍처 내에서의 유연한 결합:**
정의된 CSS 변수는 인라인 스타일, CSS 모듈, 혹은 styled-components와 같은 CSS-in-JS 라이브러리 내부에서 모두 호환되어 사용 가능합니다 [19]. 이는 특정 스타일링 패러다임에 종속되지 않고 애플리케이션의 시각적 일관성을 유지할 수 있도록 도와줍니다 [19, 20].
## 🔗 Knowledge Connections
- **Related Topics:** `[[Design Tokens|Design Tokens]]`, `Dynamic Theming`, `Tailwind CSS v4`, `[[React Server Components (RSC)|React Server Components (RSC]]`, `[[Styled Components|Styled Components]]`
- **Projects/Contexts:** `[[Next.js App Router|Next.js App Router]]` (RSC 환경 도입으로 인한 CSS-in-JS의 한계 및 CSS 변수를 활용한 테마 관리 체계로의 전환 맥락 [15-17]), `Figma DesignSystem Integration` ([[Figma|Figma]]에서 정의된 토큰을 CSS 변수로 변환하여 자동화된 워크플로우를 구축하는 프로젝트 환경 [21-23])
- **Contradictions/Notes:** 기존 CSS-in-JS 라이브러리(styled-components, Emotion)는 런타임에 JavaScript로 스타일을 생성하여 컴포넌트 수준의 강력한 동적 스타일링을 제공했으나 렌더링 성능과 RSC 호환성에서 단점이 존재했습니다. 최근에는 런타임 오버헤드가 없는 정적 빌드타임 CSS 변수(Tailwind CSS v4, [[vanilla-extract|vanilla-extract]]) 기반 접근법이 규모가 큰 프로덕션 환경에서 더욱 선호되는 추세입니다 [16, 17, 24-26].
---
*Last updated: 2026-04-26*
@@ -1,24 +0,0 @@
# [[CSS 구조 설계 방식|CSS 구조 설계 방식]]
## 📌 Brief Summary
CSS 구조 설계 방식은 웹 프론트엔드 프로젝트가 대규모로 확장됨에 따라 발생하는 전역 네임스페이스 충돌, 특수성(specificity) 전쟁, 그리고 CSS 비대화(bloat) 문제를 해결하고 코드의 유지보수성을 확보하기 위한 방법론입니다 [1]. 전통적인 BEM과 같은 수동적인 네이밍 규칙부터, 빌드 시점에 자동으로 로컬 스코프(scope)를 분리하는 [[CSS Modules|CSS Modules]], 유틸리티 퍼스트(Utility-first) 접근을 취하는 [[Tailwind CSS|Tailwind CSS]] 등 다양한 패러다임으로 진화해 왔습니다 [2], [3], [4]. 현대의 CSS 아키텍처는 단순한 시각적 장식을 넘어, 팀 협업 환경에서 예측 가능하고 확장 가능한 컴포넌트 기반 시스템을 구축하는 것을 핵심 목적으로 합니다 [5], [6], [7].
## 📖 Core Content
* **전통적 모듈화 방법론 (BEM 구조):**
BEM(Block Element Modifier)은 클래스 이름을 통해 캡슐화를 모방하는 엄격한 네이밍 규칙입니다 [8]. UI를 독립적인 '블록(Block)', 그 내부의 '엘리먼트(Element)', 상태나 외형 변화를 나타내는 '모디파이어(Modifier)'로 분류하여 구조화합니다 [9], [10], [11], [12]. 이를 통해 선택자의 깊이를 얕게(flat) 유지하고 낮은 결합도와 높은 응집도를 촉진합니다 [12]. 하지만 대규모 프로젝트에서는 개발자의 실수로 인한 전역 충돌의 위험이 여전히 존재하며, 사용하지 않는 데드 코드(dead code)를 자동으로 제거하기 어렵다는 한계가 있습니다 [13].
* **자동화된 스코핑과 캡슐화 (CSS Modules):**
CSS Modules는 빌드 도구를 통해 고유한 해시(hashed) 클래스명을 생성함으로써 자동으로 로컬 스코프를 보장합니다 [3], [14]. [[SCSS|SCSS]]와 같은 기존 프리프로세서와 잘 호환되며 전통적인 CSS 작성 방식을 그대로 유지할 수 있습니다 [15], [16]. 스타일 유출이나 충돌을 원천적으로 방지하여 유지보수성을 크게 향상시키며, 제로 런타임(Zero-runtime)으로 동작하여 런타임 성능 저하가 없습니다 [15], [17].
* **유틸리티 퍼스트 접근법 (Tailwind CSS):**
Tailwind CSS는 사전에 정의된 단일 목적의 작은 유틸리티 클래스들을 조합하여 HTML이나 JSX 내에서 직접 스타일을 작성하는 방식입니다 [18], [4]. 디자인 시스템의 일관성을 강제하기 쉽고, JIT(Just-In-Time) 컴파일러를 통해 사용된 클래스만 빌드 결과물에 포함시켜 프로덕션 CSS 번들 크기를 획기적으로 줄여줍니다 [19], [4], [20]. 다만, 마크업이 매우 장황해지고(verbose) 임의의 값(arbitrary values)이 남용될 우려가 있으며, 컴포넌트 전반의 스타일을 변경할 때 유지보수가 까다로울 수 있습니다 [19], [21], [20].
* **런타임 기반 스타일링의 한계 ([[CSS-in-JS|CSS-in-JS]]):**
[[styled-components|styled-components]]나 Emotion과 같은 CSS-in-JS는 JavaScript 코드 내에 스타일을 작성하여 컴포넌트 로직과 스타일을 함께 배치하는 방식입니다 [22], [23]. 동적 테마 적용이나 props를 활용한 스타일링에 매우 유리하지만, 런타임에 CSS를 파싱하고 주입해야 하므로 성능 오버헤드와 자바스크립트 번들 크기 증가가 발생합니다 [24], [25], [26], [23]. 특히 최근의 [[React Server Components|React Server Components]](RSC) 환경에서는 컨텍스트(Context) 기반의 CSS-in-JS가 호환되지 않는 치명적인 문제가 있어, 빌드 시점에 정적 CSS를 생성하는 Vanilla Extract 같은 제로 런타임 도구나 CSS Modules, Tailwind로 전환되는 추세입니다 [27], [28], [29].
* **실무에서의 혼합 전략 (Hybrid Approach):**
규모가 큰 엔지니어링 팀들은 단일 도구에 얽매이지 않고 각 방식의 장점을 결합하여 사용하기도 합니다 [30]. 예를 들어, 전반적인 레이아웃과 간격에는 개발 속도가 빠른 Tailwind CSS를 적용하고, 복잡한 애니메이션이나 정밀한 제어가 필요한 컴포넌트에는 CSS Modules나 SCSS를 결합하여 사용하는 하이브리드 전략을 채택함으로써 개발 생산성과 애플리케이션 성능을 동시에 최적화할 수 있습니다 [31], [32], [30], [33].
## 🔗 Knowledge Connections
- **Related Topics:** [[BEM|BEM]], CSS Modules, Tailwind CSS, [[CSS-in-JS|CSS-in-JS]], [[유틸리티 퍼스트(Utility-first)|유틸리티 퍼스트(Utility-first]]
- **Projects/Contexts:** [[대규모 프론트엔드 프로젝트 아키텍처|대규모 프론트엔드 프로젝트 아키텍처]], 디자인 시스템 기반 컴포넌트 개발, React Server Components(RSC) 환경의 스타일링 최적화
- **Contradictions/Notes:** Tailwind CSS는 클래스 네이밍에 대한 고민을 줄이고 빠른 프로토타이핑을 가능하게 하여 일관성과 CSS 번들 사이즈 최적화에 기여하지만 [19], [4], 개발자에 따라서는 인라인 스타일을 작성하는 것과 다름없어 HTML 마크업을 심각하게 어지럽히고 추상화 레이어를 불필요하게 추가한다는 강한 비판도 존재합니다 [34], [35], [19], [20]. 반면, CSS-in-JS는 컴포넌트 캡슐화에 매우 효과적이나 [22], 런타임 비용 및 서버 컴포넌트 호환성 이슈로 인해 2025년 기준 신규 아키텍처에서는 지양되고 CSS Modules가 더 안정적인 대안으로 추천되기도 합니다 [24], [36], [27], [37].
---
*Last updated: 2026-04-26*
@@ -1,22 +0,0 @@
# [[CSS 성능 최적화(CSS Performance Optimization)|CSS 성능 최적화(CSS Performance Optimization]]
## 📌 Brief Summary
CSS 성능 최적화는 웹 페이지의 렌더링을 차단하는 요소를 줄이고 불필요한 리플로우(Reflow)와 리페인트(Repaint) 연산을 최소화하여 빠르고 매끄러운 사용자 인터페이스를 제공하는 과정입니다 [1-3]. 선택자 단순화, CSS 파일 분할 및 에셋 로딩 최적화, 하드웨어 가속(GPU)을 활용한 애니메이션 최적화 등을 포함합니다 [4-7]. 궁극적으로 브라우저의 렌더링 파이프라인 부담을 줄여 사용자 경험과 유지보수성을 동시에 향상시키는 것을 목적으로 합니다 [1, 3, 8].
## 📖 Core Content
* **렌더링 블로킹 및 [[CSSOM|CSSOM]] 최적화:**
브라우저가 화면을 그리기 위해서는 DOM과 CSSOM 트리를 모두 구성해야 하므로, CSS는 기본적으로 렌더링을 차단(Render-[[Blocking|Blocking]])합니다 [9]. 이를 최적화하기 위해 미디어 쿼리(`media` 속성)를 사용하여 인쇄용이나 특정 화면용 CSS를 모듈 단위로 분리하면 초기 렌더링 차단 시간을 줄일 수 있습니다 [4, 10]. 또한, 사용하지 않는 CSS를 제거하고 코드를 최소화(Minify) 및 압축해야 하며, 복잡성을 낮춘 단순한 선택자를 작성하여 파싱 시간을 줄이는 것이 중요합니다 [4, 8, 11]. 중요한 CSS 파일이나 폰트는 `<link rel="preload">`를 활용해 조기에 로딩하는 것이 권장됩니다 [5].
* **리플로우(Reflow)와 리페인트(Repaint) 최소화:**
요소의 너비, 높이, 마진 등 레이아웃에 영향을 주는 변경은 화면 전체나 일부를 다시 계산하는 리플로우를 유발하며, 이는 브라우저 성능에 가장 큰 비용을 발생시킵니다 [2, 3, 12, 13]. 배경색이나 가시성 등 시각적 요소의 변경은 리페인트를 유발합니다 [2, 14]. 이러한 연산을 최소화하려면 여러 인라인 스타일을 설정하는 것을 피하고 DOM 트리의 가장 낮은 하위 레벨에서 클래스를 변경해야 합니다 [15, 16]. 또한, 자바스크립트를 이용해 DOM에 대해 읽기와 쓰기를 반복하는 '레이아웃 스래싱([[Layout Thrashing|Layout Thrashing]])'을 방지하기 위해 DOM 업데이트를 일괄 처리(Batch)하는 기술이 필요합니다 [17-19].
* **애니메이션 최적화:**
`width`, `height`, `box-shadow` 와 같이 리플로우나 과도한 리페인트를 유발하는 속성의 애니메이션은 피해야 합니다 [7, 12, 20]. 대신 레이아웃 재계산을 유발하지 않는 `transform`이나 `opacity` 속성을 활용하면 브라우저가 애니메이션 처리를 GPU에 위임(하드웨어 가속)하여 60fps의 부드러운 성능을 확보할 수 있습니다 [7, 21-23]. 과도한 수의 동시 애니메이션이나 거대한 배경 이미지 사용은 지양해야 하며, 상태가 변할 특정 요소에는 `will-change` 속성을 주어 브라우저가 사전에 최적화할 수 있게 힌트를 제공할 수 있습니다 [20, 24-26].
* **렌더링 격리(Containment) 활용:**
CSS Containment 모듈의 `contain`이나 `content-visibility` 속성을 사용하면, 브라우저가 페이지의 특정 컨테이너를 다른 DOM 요소와 분리하여 독립적으로 렌더링 최적화를 수행하도록 지시할 수 있습니다 [27, 28]. 화면에 보이기 전까지는 해당 컨테이너의 레이아웃과 렌더링을 생략할 수 있어 성능이 크게 향상됩니다 [28].
## 🔗 Knowledge Connections
- **Related Topics:** 애니메이션 (transition / keyframes), [[CSS 구조 설계 방식|CSS 구조 설계 방식]], 리플로우와 리페인트(Reflows & Repaints), [[CSS Modules|CSS Modules]]
- **Projects/Contexts:** [[실무에서 CSS 관리하는 방법|실무에서 CSS 관리하는 방법]]
- **Contradictions/Notes:** 컴포넌트 기반 아키텍처에서 [[styled-components|styled-components]]와 같은 런타임 CSS-in-JS 방식은 동적 스타일링에 유리하지만, 브라우저 런타임에 CSS를 파싱하고 주입해야 하므로 성능 오버헤드와 렌더링 속도 저하를 유발할 수 있습니다 [29, 30]. 반면 성능이 중요한 환경에서는 정적 CSS를 생성하는 CSS Modules나 [[Tailwind CSS|Tailwind CSS]] 같은 Zero-runtime 방식이 성능 상 더 권장됩니다 [31-34]. 또한 브라우저 최적화를 돕는 `will-change` 속성은 성능 문제를 미리 방지하고자 너무 많은 요소에 남용할 경우 오히려 브라우저의 리소스를 소모해 성능 저하를 일으킬 수 있으므로 최후의 수단으로만 사용해야 합니다 [24, 25].
---
*Last updated: 2026-04-26*
@@ -1,20 +0,0 @@
# [[CSS 애니메이션 성능(CSS Animation Performance)|CSS 애니메이션 성능(CSS Animation Performance]]
## 📌 Brief Summary
CSS 애니메이션 성능(CSS Animation Performance) 최적화는 웹 애플리케이션에서 애니메이션이 브라우저의 렌더링 엔진에 미치는 부하를 줄여 끊김 없는(jank-free) 부드러운 사용자 경험을 제공하기 위한 기술적 접근입니다. 레이아웃 재계산(Reflow)과 화면 다시 그리기(Repaint)를 유발하는 속성의 애니메이션을 피하고 GPU 가속을 활용할 수 있는 속성으로 대체하는 것이 핵심입니다. 최적화되지 않은 애니메이션은 기기의 리소스를 낭비하고 렌더링 속도를 늦춰 전반적인 유지보수성과 UX를 크게 저해할 수 있습니다 [1-3].
## 📖 Core Content
* **Reflow 및 Repaint를 유발하는 속성 애니메이션 피하기**: `width`, `height`, `margin`, `padding`, `top`, `left`, `bottom`, `right`와 같은 기하학적 형태나 레이아웃에 영향을 주는 속성은 브라우저의 레이아웃 재계산(Reflow 또는 [[Layout Thrashing|Layout Thrashing]])과 다시 그리기(Repaint)를 유발하여 성능을 크게 저하시킵니다 [3-6].
* **GPU 가속을 활용한 속성(Transform, Opacity) 사용**: 레이아웃 변경을 피하기 위해 `width``height` 대신 `transform`(`scale`, `translateZ()`, `rotate3d()`)을, 색상 변화 대신 `opacity``filter`를 사용해야 합니다 [6-9]. 이를 통해 브라우저가 애니메이션 작업을 기본 스레드에서 기기의 GPU로 넘겨 처리(Compositing)하게 함으로써 렌더링 성능을 향상시킬 수 있습니다 [7-9].
* **비용이 많이 드는 시각적 속성 자제**: `box-shadow`, `border-radius`, `filter` 등의 속성이나 거대하고 복잡한 배경 이미지의 애니메이션은 브라우저의 블렌딩 및 합성 리소스를 매우 많이 소모하므로 사용을 최소화해야 합니다 [9-11]. 복잡한 이미지 대신 SVG나 단순한 CSS 그레이디언트를 활용하는 것이 훨씬 부드럽고 빠른 애니메이션을 보장합니다 [12].
* **애니메이션 개수 및 무한 루프 제한**: 한 번에 너무 많은 요소를 동시에 애니메이션하거나 불필요한 무한 루프(`infinite`)를 돌리면 시스템 리소스가 고갈되고 초당 프레임(FPS)이 떨어집니다 [10, 13, 14]. 화면에 보이지 않는 요소의 애니메이션은 `animation-play-[[State|State]]`를 이용해 일시 정지시키고, 필수적인 UI 요소에만 제한적으로 애니메이션을 적용해야 합니다 [3, 13, 14].
* **`will-change` 속성의 전략적 사용**: 애니메이션이 예상되는 요소에 `will-change` 속성을 부여하면, 브라우저가 미리 렌더링 최적화(예: GPU 레이어 분리)를 준비할 수 있게 힌트를 줄 수 있습니다 [8, 13, 15]. 단, 과도하게 사용할 경우 오히려 브라우저의 성능 문제를 일으킬 수 있으므로 최후의 수단으로만 사용해야 합니다 [11, 15].
* **타이밍 및 성능 테스트**: 부드럽고 자연스러운 느낌을 위해 애니메이션 지속 시간은 보통 200~500ms로 짧게 유지하고 선형적(Linear) 전환보다는 Easing 함수(`ease-in-out` 등)를 사용해야 합니다 [16]. 배포 전에는 [[Chrome DevTools|Chrome DevTools]]의 [[Performance Panel|Performance Panel]]과 Layer Profiler 등을 활용하여 프레임 드롭이나 렌더링 병목 현상을 검증해야 합니다 [6, 17].
## 🔗 Knowledge Connections
- **Related Topics:** Reflow와 Repaint(Reflows and Repaints), [[GPU 가속(GPU Acceleration)|GPU 가속(GPU Acceleration]], CSS 구조 설계 방식, [[반응형 디자인|반응형 디자인]]
- **Projects/Contexts:** 대규모 프론트엔드 프로젝트의 CSS 최적화(Performance [[Optimization|Optimization]] in [[CSS Architecture|CSS Architecture]]), UX 개선을 위한 애니메이션 통합(Integrating Animation in UX)
- **Contradictions/Notes:** 소스 자료들은 UI에서 애니메이션이 사용자 경험(UX)을 향상하고 브랜드 개성을 살리는 중요한 소통 수단이라고 권장하지만, 동시에 목적 없는 과도한 애니메이션이나 성능을 고려하지 않은 구현은 사용자에게 인지적 과부하를 주거나 기기 성능을 떨어뜨려 오히려 심각한 경험 저하를 낳을 수 있다고 주의를 주고 있습니다 [2, 16, 18]. 따라서 "예쁘게" 만드는 것을 넘어 "유지보수 가능하고 최적화된(Performant)" 상태를 유지하는 것이 강조됩니다.
---
*Last updated: 2026-04-26*
@@ -1,31 +0,0 @@
# [[CSS 애니메이션 최적화(CSS Animations Optimization)|CSS 애니메이션 최적화(CSS Animations Optimization]]
## 📌Brief만 Summary
CSS 애니메이션 최적화는 웹 인터페이스의 애니메이션이 브라우저 성능을 저하시키거나 사용자 경험을 해치지 않도록 구현하는 기법입니다. 불필요한 레이아웃 재계산(Reflow)과 화면 다시 그리기(Repaint)를 유발하는 속성 사용을 피하고, GPU 가속 및 브라우저 최적화 힌트를 활용하여 화면의 버벅거림(Jank) 현상을 방지합니다. 이를 통해 모바일 및 저사양 기기에서도 부드럽고 응답성 높은 인터페이스를 유지보수 가능하게 설계할 수 있습니다.
## 📖 Core Content
**리플로우(Reflow)와 리페인트(Repaint) 최소화**
* 웹 브라우저에서 성능을 가장 크게 저하시키는 주요 원인은 리플로우(레이아웃 재계산)와 리페인트(시각적 요소 재렌더링)입니다 [1-3].
* 애니메이션을 적용할 때 `width`, `height`, `margin`, `padding`, `top`, `bottom`, `left`, `right` 등 요소의 기하학적 크기나 위치를 변경하는 속성은 리플로우를 유발하므로 애니메이션에 사용하는 것을 피해야 합니다 [4-6].
* 대신 레이아웃에 영향을 주지 않는 `transform`(예: `scale`, `translateZ()`)과 `opacity` 속성을 활용하면 리플로우와 리페인트를 방지할 수 있습니다 [6-8].
**고비용 속성 및 과도한 애니메이션 회피**
* `box-shadow`, `filter`, `border-radius`와 같은 속성은 렌더링에 많은 자원을 소모하므로 애니메이션 적용 시 성능 병목 현상을 일으킬 수 있어 가급적 피하는 것이 좋습니다 [8, 9].
* 크고 복잡한 비트맵 배경 이미지를 애니메이션화하는 것은 성능을 크게 저하시키므로, 해상도에 독립적이고 가벼운 SVG나 간단한 CSS 그라디언트를 활용하는 것이 효율적입니다 [10, 11].
* 무수히 많은 요소를 동시에 애니메이션 처리하거나 불필요한 무한 루프(`infinite`)를 적용하면 프레임 속도(FPS)가 급격히 떨어집니다 [9, 12, 13]. 화면에서 보이지 않는 상태일 때는 `animation-play-[[State|State]]`를 사용해 애니메이션을 일시 정지하는 방식으로 자원을 아껴야 합니다 [1, 13].
**GPU 가속 및 브라우저 최적화 기능 활용**
* `transform``opacity`를 사용하면 브라우저가 애니메이션 처리를 메인 스레드에서 분리하여 GPU로 넘기는 컴포지팅(Compositing) 과정을 거치게 되어 성능이 대폭 향상됩니다 [7, 8, 14].
* 문서의 흐름에서 벗어난 `position: absolute` 또는 `position: fixed` 요소에 애니메이션을 적용하면, 주변 요소의 레이아웃에 영향을 미치지 않기 때문에 전체 리플로우 대신 덜 비용이 드는 리페인트만 발생시킵니다 [15-17].
* `will-change` 속성을 사용하면 브라우저에 어떤 요소가 변경될지 미리 힌트를 주어 렌더링 최적화를 준비하게 할 수 있습니다 [12, 18, 19]. 또한 JS 기반 애니메이션을 쓴다면 브라우저의 리페인트 주기와 동기화되는 `requestAnimationFrame`을 사용해야 합니다 [19].
**접근성([[Accessibility|Accessibility]]) 고려**
* 과도한 움직임은 전정기관 장애가 있는 사용자 등에게 불편함이나 멀미를 유발할 수 있습니다 [20, 21]. 이를 방지하기 위해 `prefers-reduced-motion` 미디어 쿼리를 사용하여 사용자의 OS 설정에 따라 애니메이션을 줄이거나 끄도록 제어해야 합니다 [20-22].
## 🔗 Knowledge Connections
- **Related Topics:** [[Reflow와 Repaint(리플로우와 리페인트)|Reflow와 Repaint(리플로우와 리페인트]], GPU 가속 및 Compositing, [[웹 접근성 및 prefers-reduced-motion|웹 접근성 및 prefers-reduced-motion]]
- **Projects/Contexts:** [[실무에서의 프론트엔드 성능 최적화|실무에서의 프론트엔드 성능 최적화]], [[유지보수 가능하고 확장 가능한 CSS 아키텍처 설계|유지보수 가능하고 확장 가능한 CSS 아키텍처 설계]]
- **Contradictions/Notes:** 브라우저의 성능을 끌어올리기 위해 `will-change` 속성을 사용할 수 있지만, 이 속성 자체도 자원을 소모하므로 불필요하게 많은 요소에 남용할 경우 오히려 브라우저를 과부하에 빠뜨려 성능 저하를 유발할 수 있습니다. 따라서 기존의 성능 문제를 해결하기 위한 '최후의 수단'으로만 엄격히 제한하여 사용해야 합니다 [10, 12, 18]. 또한 애니메이션을 부드럽게 하기 위해 1px 단위로 조작하는 것이 보기에는 좋을 수 있으나, 저사양 기기에서는 CPU를 과도하게 사용하게 되므로 차라리 3px 단위로 조작하여 매끄러움을 약간 타협하고 렌더링 속도를 확보하는 것이 실무적으로 좋은 해결책이 될 수 있습니다 [17].
---
*Last updated: 2026-04-26*
@@ -1,28 +0,0 @@
# [[CSS 애니메이션 최적화(Optimizing CSS Animations)|CSS 애니메이션 최적화(Optimizing CSS Animations]]
## 📌 Brief Summary
CSS 애니메이션 최적화는 웹 페이지 내 애니메이션이 성능 저하나 끊김(Jank) 현상 없이 부드럽게 실행되도록 브라우저의 렌더링 과정을 개선하는 기법입니다 [1, 2]. 브라우저의 레이아웃 재계산(Reflow)과 화면 다시 그리기(Repaint)를 유발하는 속성 사용을 피하고, GPU 가속을 활용할 수 있는 속성을 중점적으로 사용하는 것이 핵심입니다 [3-5]. 이를 통해 사용자에게 쾌적하고 반응성 높은 인터페이스(UX)를 제공하는 동시에 디바이스의 리소스 소모를 최소화할 수 있습니다 [1, 6, 7].
## 📖 Core 기Content
* **Reflow 및 Repaint 유발 속성 최소화**
웹 브라우저의 렌더링 파이프라인에서 애니메이션 최적화의 가장 큰 적은 레이아웃 변형(Reflow)과 재도색(Repaint)입니다 [8]. `width`, `height`, `margin`, `padding`, `top`, `left`, `align-items` 등의 속성을 애니메이션 처리하면 브라우저가 매 프레임마다 레이아웃을 다시 계산해야 하므로 성능이 크게 저하됩니다 [3, 5]. 또한 `box-shadow`, `border-radius`, `filter`와 같이 렌더링 비용이 많이 드는 속성 역시 무거운 컴퓨팅 연산을 요구합니다 [3, 9]. 따라서 위치 이동이나 크기 조절이 필요할 때는 Reflow를 유발하지 않는 `transform`(예: `scale`, `translate`)과 `opacity` 속성을 사용하는 것이 권장됩니다 [4, 9, 10].
* **GPU 가속 활용 (Compositing)**
메인 스레드에서 처리되는 애니메이션 작업을 기기의 GPU로 넘기면 성능, 특히 모바일 기기에서의 성능을 크게 향상시킬 수 있습니다 [4, 11]. `transform: translateZ()``rotate3d()` 같은 3D 변환 속성, `opacity`, 그리고 별도의 렌더링 레이어를 갖는 요소(`<video>`, `<canvas>` 등)는 브라우저가 자동으로 GPU를 활용해 처리합니다 [4, 11]. `position: fixed``absolute`가 적용된 요소에 애니메이션을 적용하는 것도 레이아웃에 영향을 주지 않아 성능 개선에 도움이 됩니다 [12, 13].
* **will-change 속성의 올바른 사용**
`will-change` 속성은 특정 요소가 변경될 것임을 브라우저에 미리 알려주어 브라우저가 사전에 최적화를 준비할 수 있게 합니다 [14, 15]. 하지만 이 속성을 너무 많은 요소에 불필요하게 적용하면 오히려 브라우저의 시스템 리소스를 소모시켜 성능 문제를 야기할 수 있습니다 [14, 15]. 따라서 사전 대비용으로 남용하기보다는 성능 문제가 이미 발생한 경우 이를 해결하기 위한 최후의 수단으로 제한적으로 사용해야 합니다 [14].
* **애니메이션 실행 제어 및 리소스 관리**
너무 많은 요소를 동시에 애니메이션 처리하거나, 거대한 비트맵 이미지 및 복잡한 그라디언트 배경을 애니메이션으로 전환하면 브라우저 엔진에 큰 부담을 줍니다 [16, 17]. 이를 방지하기 위해 가벼운 SVG나 단순한 CSS 그라디언트를 활용하는 것이 좋습니다 [18]. 또한 불필요한 무한 반복 애니메이션(`infinite`)은 시스템 리소스를 계속 소모하므로 횟수를 제한하거나, 요소가 화면에서 벗어났을 때 `animation-play-[[State|State]]`를 이용해 애니메이션을 일시 정지시켜야 합니다 [8, 19].
* **UX를 고려한 접근성 ([[Accessibility|Accessibility]]) 최적화**
모든 사용자나 기기가 애니메이션을 매끄럽게 소화할 수 있는 것은 아닙니다 [6, 20]. 전정기관 장애가 있는 사용자는 과도한 움직임으로 인해 어지러움을 느낄 수 있으며, 저사양 기기나 배터리가 부족한 모바일 기기 사용자에게는 애니메이션이 부담될 수 있습니다 [6, 20]. 이를 위해 `prefers-reduced-motion` 미디어 쿼리를 사용하여 운영체제 수준에서 애니메이션 감소를 설정한 사용자에게는 애니메이션을 제한하거나 제공하지 않는 방식의 최적화가 필요합니다 [6, 20].
## 🔗 Knowledge Connections
- **Related Topics:** [[Reflow & Repaint|Reflow & Repaint]], [[GPU 가속(GPU Acceleration)|GPU 가속(GPU Acceleration]], UX 애니메이션(UX Animation), will-change 속성, prefers-reduced-motion, 접근성(Accessibility)
- **Projects/Contexts:** 대규모 프론트엔드 프로젝트의 UI/UX 성능 최적화, 디자인 시스템 기반의 인터페이스 애니메이션 적용 및 검증 과정
- **Contradictions/Notes:** 브라우저 성능 최적화를 돕는 `will-change` 속성은 잘 쓰면 반응성을 높이지만 무분별하게 남용될 경우 도리어 심각한 리소스 낭비 및 성능 저하를 일으키는 양면성이 있어 주의가 필요합니다 [14, 15]. 또한 화려한 애니메이션이 사용자 경험을 즐겁게 만들 수 있으나, 지나칠 경우 인지적 과부하를 일으키거나 성능 저하를 초래해 오히려 UX를 해칠 수 있습니다 [1-3].
---
*Last updated: 2026-04-26*
@@ -1,25 +0,0 @@
# [[CSS-in-JS|CSS-in-JS]]
## 📌 Brief Summary
CSS-in-JS는 [[JavaScript|JavaScript]] 파일 내에 직접 CSS를 작성하여 스타일과 컴포넌트를 같은 위치(co-location)에 배치하는 프론트엔드 스타일링 접근 방식입니다. 대표적인 라이브러리로 styled-components와 Emotion 등이 있으며, 템플릿 리터럴을 활용해 컴포넌트의 상태나 props에 기반한 동적 스타일링을 자연스럽게 지원합니다. 하지만 런타임에 CSS를 생성하고 주입하는 과정에서 발생하는 성능 오버헤드와 React Server Components(RSC)와의 호환성 문제로 인해 최근에는 Zero-runtime 방식이나 유틸리티 퍼스트 프레임워크([[Tailwind CSS|Tailwind CSS]] 등)와 비교되며 아키텍처적 재평가가 이루어지고 있습니다.
## 📖 Core Content
* **주요 장점 및 특징:**
CSS-in-JS는 자바스크립트의 변수, 상태, props 등을 직접 활용해 동적인 스타일링을 손쉽게 구현할 수 있게 해줍니다 [1]. 컴포넌트와 스타일이 같은 파일에 공존하므로 컴포넌트 삭제 시 스타일도 함께 제거되어 유지보수가 용이하며, 과거 CSS의 전역 네임스페이스 충돌 문제나 스타일이 엇나가는 문제를 효과적으로 해결합니다 [1, 2]. 또한 내부적인 테마 프로바이더(Theme Provider)를 통해 라이트/다크 모드 등 다중 테마 관리가 수월하며, TypeScript를 통한 타입 안전성도 제공합니다 [1, 2].
* **런타임 성능 및 번들 사이즈 한계:**
가장 큰 단점은 브라우저 런타임 시 자바스크립트를 실행하여 CSS 문자열을 생성하고 `<style>` 태그로 주입해야 한다는 점입니다 [1, 3]. 이는 추가적인 자바스크립트 번들 사이즈(예: styled-components 약 30kb, Emotion 약 12kb 추가)를 유발하고, CPU 사이클을 소모하여 First Input Delay(FID)나 Interaction to Next Paint(INP) 등 [[Core Web Vitals|Core Web Vitals]] 지표에 부정적인 영향을 미칩니다 [1, 3-5]. 정량적 벤치마크에 따르면 10,000개의 리스트 아이템을 렌더링할 때 Tailwind CSS는 85ms가 걸린 반면, [[Styled Components|Styled Components]]는 148ms가 소요되어 약 63%의 성능 격차를 보였습니다 [6].
* **[[React Server Components (RSC)|React Server Components (RSC]] 호환성 문제:**
[[Next.js App Router|Next.js App Router]]와 RSC 환경에서 런타임 중심의 CSS-in-JS는 큰 기술적 마찰을 겪고 있습니다. styled-components나 Emotion 같이 React Context 기반의 테마를 사용하는 라이브러리는 컨텍스트가 존재하지 않는 서버 컴포넌트 환경과 근본적으로 호환되지 않습니다 [4, 7, 8]. 이를 해결하기 위해 Next.js 15 등에서는 서버 렌더링 중 CSS 규칙을 수집하여 주입하는 '[[Style Registry|Style Registry]]' 패턴을 도입하고, 컴파일러 설정을 통해 클라이언트와 서버 간의 하이드레이션([[Hydration|Hydration]]) 불일치를 방지하는 우회적인 방식을 사용해야만 합니다 [9, 10].
* **대안적 접근 ([[Zero-Runtime CSS-in-JS|Zero-Runtime CSS-in-JS]]):**
런타임 오버헤드와 RSC 호환성 문제를 해결하기 위해 `[[vanilla-extract|vanilla-extract]]`와 같은 Zero-runtime CSS-in-JS 라이브러리가 강력한 대안으로 부상하고 있습니다 [7, 11]. 이 방식은 런타임 자바스크립트 오버헤드 없이 빌드 타임에 정적 CSS를 생성하며, TypeScript를 기반으로 타입 안전한 스타일링을 제공하여 대규모 디자인 시스템 관리에 유리합니다 [11, 12].
## 🔗 Knowledge Connections
- **Related Topics:** [[styled-components|styled-components]], Tailwind CSS, React Server Components, [[Zero-Runtime CSS-in-JS|Zero-runtime CSS-in-JS]]
- **Projects/Contexts:** [[Next.js App Router Migration|Next.js App Router Migration]], DesignSystem Architecture, [[Performance Optimization|Performance Optimization]]
- **Contradictions/Notes:** CSS-in-JS는 컴포넌트와 스타일의 통합으로 개발자 경험(DX)을 극대화한다는 강점이 있으나, 여러 엔터프라이즈급 성능 감사 결과에서는 Styled Components 대신 런타임 오버헤드가 없는 Tailwind CSS나 정적 CSS 방식으로 전환했을 때 모바일 환경의 INP(Interaction to Next Paint) 지표가 58.4% 향상되는 등 런타임 비용의 한계가 강하게 지적되고 있습니다 [1, 5, 13].
---
*Last updated: 2026-04-26*
@@ -1,18 +0,0 @@
# [[CSSOM(CSS Object Model)|CSSOM(CSS Object Model]]
## 📌 Brief Summary
[[CSSOM|CSSOM]](CSS Object Model)은 웹 페이지의 DOM(Document Object Model) 요소들이 어떻게 스타일링되는지에 대한 모든 정보를 담고 있는 객체 모델입니다 [1, 2]. 브라우저가 제공받은 CSS 규칙을 파싱하여 부모, 자식, 형제 관계를 가진 노드 트리 형태로 구성합니다 [3, 4]. 완성된 CSSOM은 DOM과 결합하여 화면에 픽셀을 그리기 위한 렌더 트리([[Render Tree|Render Tree]])를 생성하는 데 필수적인 역할을 합니다 [5, 6].
## 📖 Core Content
- **렌더링 차단 특성 (Render-[[Blocking|Blocking]]):** DOM 트리의 생성은 점진적으로 이루어지지만, CSSOM 생성은 점진적이지 않은 렌더링 차단(render-blocking) 작업입니다 [1, 2]. 브라우저는 스타일이 적용되지 않은 날 것의 HTML 콘텐츠가 화면에 번쩍이며 나타나는 현상(FOUC, Flash of Unstyled Content)을 방지하기 위해, 연결된 모든 스타일시트를 다운로드하고 처리하여 CSSOM이 완성될 때까지 페이지 렌더링을 차단합니다 [1, 2].
- **트리 구조와 캐스케이딩 (Cascading):** CSSOM은 CSS 규칙에 따라 노드 트리를 형성하며, 하위 노드는 상위 노드의 스타일 일부를 상속받습니다(하향식 종속) [3, 7]. 이후에 파싱된 규칙이 이전 규칙을 덮어쓸 수 있는 속성이 있으므로, 브라우저는 전체 CSS가 완전히 파싱될 때까지 CSSOM을 렌더 트리 구성에 사용할 수 없습니다 [7]. CSSOM 트리에는 브라우저의 기본 사용자 에이전트(User Agent) 스타일시트 정보도 포함되어 있으며, 브라우저는 가장 일반적인 규칙부터 구체적인 규칙을 거듭 적용하여 최종 스타일을 계산합니다 [8].
- **선택자 파싱 원리와 성능:** 브라우저는 CSS 선택자를 오른쪽에서 왼쪽으로 파싱합니다 [9]. 따라서 클래스 여러 개가 결합된 구체적인 선택자(예: `.container.navigation.item`)는 조상 관계를 확인하기 위해 DOM 트리를 거슬러 올라가야 하므로, 단순한 선택자(예: `.item`)에 비해 브라우저에 약간의 작업 부하를 더 줍니다 [9, 10].
- **렌더 트리(Render Tree)와의 결합:** 브라우저는 화면에 표시될 요소의 레이아웃을 계산하기 위해 DOM 트리와 CSSOM 트리를 병합하여 렌더 트리를 만듭니다 [6, 11]. DOM 트리의 루트에서 시작해 눈에 보이는 각 노드를 순회하며 적절한 CSSOM 규칙을 찾아 적용합니다 [6]. 이때 화면에 시각적 영향을 주지 않는 노드나 `display: none` 스타일이 적용된 노드는 렌더 트리에서 제외됩니다 [6, 11].
## 🔗 Knowledge Connections
- **Related Topics:** [[DOM (Document Object Model)|DOM(Document Object Model]], Render Tree, Critical Rendering Path, [[Reflow & Repaint|Reflow & Repaint]]
- **Projects/Contexts:** 브라우저 렌더링 최적화([[Browser|Browser]] Rendering [[Optimization|Optimization]])
- **Contradictions/Notes:** 소스에 따르면 CSSOM 구축은 중요한 렌더링 차단 과정이지만, 최신 브라우저 엔진에서 CSSOM 생성 및 스타일 계산 속도는 마이크로초 단위로 이루어질 만큼 매우 빠릅니다 [8-10]. 따라서 CSS 선택자의 구체성을 낮추는 등의 마이크로 최적화보다는, 필요 없는 CSS 규칙을 최소화하거나 논블로킹(non-blocking) 요청을 적절히 사용하는 것이 더 의미 있는 성능 개선 방법이라고 지적합니다 [8, 10, 12].
---
*Last updated: 2026-04-25*
-25
View File
@@ -1,25 +0,0 @@
# [[CSSOM|CSSOM]]
## 📌 Brief Summary
[[CSSOM(CSS Object Model)|CSSOM(CSS Object Model]]은 웹 페이지의 시각적 외관을 정의하는 스타일 정보의 트리 구조입니다 [1-3]. DOM 생성과 달리 점진적으로 구성되지 않으며, 화면 렌더링을 차단(render-Blocking)하는 특징이 있습니다 [1, 2]. 구축된 CSSOM은 DOM과 결합하여 브라우저가 화면에 요소를 계산하고 그리는 데 사용하는 렌더 트리([[Render Tree|Render Tree]])를 합성하는 핵심 역할을 합니다 [3-5].
## 📖 Core Content
* **생성 과정 및 특징**
브라우저는 CSS 코드를 파싱하여 CSSOM 트리를 생성하며, 여기에는 브라우저의 기본 사용자 에이전트(user agent) 스타일시트도 포함됩니다 [6, 7]. 브라우저는 CSS 규칙을 자신이 이해할 수 있는 스타일 맵으로 변환하고, CSS 선택자를 기반으로 부모, 자식, 형제 관계를 가지는 노드 트리를 구성합니다 [6]. 이 과정에서 가장 일반적인 규칙부터 시작하여 더 구체적인 규칙을 재귀적으로 적용하며 속성값을 캐스케이딩(Cascading)합니다 [7, 8].
* **렌더링 차단 (Render-Blocking) 특성**
HTML의 DOM 생성은 점진적으로 이루어지지만 CSSOM은 그렇지 않으며 렌더링을 차단하는 작업입니다 [1, 2]. CSS 규칙은 이후에 파싱되는 규칙에 의해 덮어씌워질 수 있기 때문에, 브라우저는 스타일시트를 모두 다운로드하고 파싱하여 CSSOM을 완성할 때까지 페이지 렌더링을 중단합니다 [2, 8]. 이는 사용자가 스타일이 적용되지 않은 날 것의 HTML을 보게 되는 "스타일이 적용되지 않은 콘텐츠의 번쩍임(FOUC, Flash of Unstyled Content)" 현상을 방지하기 위한 안전장치입니다 [1].
* **선택자 복잡도와 성능**
CSS 선택자의 복잡도는 CSSOM 구성 속도에 영향을 미칩니다 [9]. 브라우저는 선택자를 오른쪽에서 왼쪽으로 파싱하기 때문에, 특정 요소를 깊게 지칭하는 구체적인 선택자일수록 브라우저 엔진이 조상 관계를 확인하기 위해 DOM 트리를 거슬러 올라가야 하므로 더 많은 연산 작업을 요구합니다 [9, 10]. 하지만 최신 브라우저의 CSSOM 구축 및 파싱 속도는 매우 빠르며, 일반적으로 DNS 조회에 걸리는 시간보다도 적게 소요됩니다 [7, 10].
* **렌더 트리(Render Tree)의 합성**
CSSOM과 DOM의 구축이 모두 준비되면, 브라우저는 이 두 트리를 결합하여 렌더 트리를 생성합니다 [4, 5, 11]. 렌더 트리는 화면에 표시되는 콘텐츠와 그에 해당하는 계산된 스타일(computed styles)만을 포함하며, `display: none`으로 스타일링된 숨김 요소나 `<head>`, `<script>` 같은 비시각적 노드는 렌더 트리에서 제외됩니다 [4, 5, 11].
## 🔗 Knowledge Connections
- **Related Topics:** [[DOM (Document Object Model)|DOM (Document Object Model]], Render Tree, [[Critical Rendering Path (CRP)|Critical Rendering Path (CRP]]
- **Projects/Contexts:** [[Browser|Browser]] Rendering Process, [[Web Performance Optimization|Web Performance Optimization]]
- **Contradictions/Notes:** 소스에 따르면 더 구체적인 CSS 선택자가 파싱 비용을 증가시키긴 하지만, 브라우저가 이를 마이크로초 단위로 처리할 만큼 속도가 매우 빠르기 때문에 선택자 성능 최적화 자체에만 집중하기보다는 CSS 파일을 최소화(minification)하거나 미디어 쿼리로 비차단(non-blocking) 요청을 분리하는 등 다른 최적화 방식이 더 큰 효과를 줄 수 있다고 조언합니다 [7, 10].
---
*Last updated: 2026-04-25*
@@ -1,22 +0,0 @@
# [[Client Components|Client Components]]
## 📌 Brief Summary
클라이언트 컴포넌트(Client Components)는 모던 React 아키텍처(예: [[Next.js 15 App Router|Next.js 15 App Router]])에서 `'use client'` 지시어로 정의되며 전통적인 React 컴포넌트처럼 동작하는 UI 요소이다 [1]. 서버 컴포넌트와 달리 클라이언트 측 자바스크립트를 실행하므로 상태([[State|State]]) 관리, 이벤트 핸들러 등 상호작용이 필요하거나 브라우저 API를 사용해야 할 때 필수적으로 적용된다 [1, 2]. 확장 가능한 프론트엔드 환경에서는 자바스크립트 번들 크기를 최소화하고 성능을 극대화하기 위해 클라이언트 컴포넌트를 작고 기능적으로 집중된 형태로 유지하는 것이 핵심 원칙이다 [2, 3].
## 📖 Core Content
* **경계 설정 및 하이드레이션([[Hydration|Hydration]]):** 클라이언트 컴포넌트는 최상단에 `'use client'` 지시어를 선언하여 클라이언트 측 자바스크립트가 시작되는 경계를 명확히 표시한다 [1]. 서버가 렌더링한 정적 HTML에 React가 이벤트 리스너와 상태를 연결하여 상호작용을 가능하게 만드는 과정인 하이드레이션(Hydration)은 [[Next.js 15|Next.js 15]] 기준으로 오직 클라이언트 컴포넌트에서만 발생한다 [4].
* **컴포넌트 합성 패턴(Composition Patterns):** 재사용 가능하고 확장성 있는 UI를 구축하기 위해 다양한 합성 패턴이 사용된다. 서버 컴포넌트가 클라이언트 컴포넌트를 하위 요소로 렌더링하거나, 반대로 서버 컴포넌트를 클라이언트 컴포넌트의 자식(children)이나 props로 전달하여 자식 요소가 서버 컴포넌트로서의 특성을 유지하게 할 수 있다 [1, 4]. 또한 클라이언트 측 상태를 앱 전반에 공유하기 위해 Context Provider 패턴을 사용하기도 한다 [4].
* **확장 가능한 프론트엔드를 위한 모범 사례:**
* 기본적으로 서버 컴포넌트를 사용하고 상호작용이 필요한 구역만 클라이언트 컴포넌트로 분리하여 작게 유지해야 한다 [2, 3].
* 레이아웃 등 최상단 요소에 불필요하게 `'use client'`를 남용하면 하위의 모든 라우트가 클라이언트 측 컴포넌트로 강제 전환되므로 주의해야 한다 [3].
* 데이터 패칭은 가급적 서버 측에서 수행하여 클라이언트 번들 크기를 줄이고 보안을 유지해야 한다 [3].
* 함수, 날짜, 클래스 인스턴스 등 직렬화할 수 없는(non-serializable) props를 서버 컴포넌트에서 클라이언트 컴포넌트로 넘겨서는 안 된다 [5].
* **스타일링 파라다임 및 테마 적용([[CSS-in-JS|CSS-in-JS]]):** Next.js App Router 아키텍처에서 styled-components와 같은 런타임 CSS-in-JS 라이브러리를 사용하려면, 렌더링 중 CSS 규칙을 수집하기 위한 '스타일 레지스트리([[Style Registry|Style Registry]])'를 구성하고 이를 클라이언트 컴포넌트로 래핑해야 한다 [6]. 더 나아가, [[React Context|React Context]] 없이도 클라이언트 컴포넌트와 서버 컴포넌트 모두에서 테마가 작동하도록 CSS 사용자 지정 속성(CSS custom properties)을 기반으로 한 `createTheme` 등의 기능이 도입되어 렌더링 컨텍스트의 한계를 극복하고 있다 [7].
## 🔗 Knowledge Connections
- **Related Topics:** [[Server Components|Server Components]], Hydration, CSS-in-JS, [[React Context|React Context]]
- **Projects/Contexts:** [[Next.js App Router|Next.js App Router]], [[styled-components|styled-components]]
- **Contradictions/Notes:** 전통적인 런타임 CSS-in-JS 라이브러리(styled-components, Emotion)는 내부적으로 React Context에 의존하기 때문에 서버 컴포넌트에서는 작동하지 않고 클라이언트 컴포넌트 래핑이 필요하지만, 대규모 프로젝트의 성능([[Core Web Vitals|Core Web Vitals]]) 향상과 Next.js App Router와의 완벽한 호환을 위해서는 런타임 비용이 없는 Tailwind CSS, [[CSS Modules|CSS Modules]] 또는 [[vanilla-extract|vanilla-extract]] 등의 정적 CSS 생성 도구로의 전환이 2025년 기준 더욱 강력히 권장되고 있다 [6, 8-11].
---
*Last updated: 2026-04-26*
@@ -1,23 +0,0 @@
# [[Client-Side Rendering (CSR)|Client-Side Rendering (CSR]]
## 📌 Brief Summary
Client-Side Rendering (CSR)은 브라우저(클라이언트)가 서버로부터 최소한의 HTML 뼈대와 [[JavaScript|JavaScript]] 번들을 전달받은 후, JavaScript를 실행하여 동적으로 웹 페이지의 콘텐츠를 렌더링하고 UI를 구축하는 방식입니다 [1-3]. 이 방식은 주로 React나 Vue와 같은 라이브러리를 통해 단일 페이지 애플리케이션(SPA) 형태로 구현됩니다 [2, 4, 5]. 초기 로딩 이후에는 전체 페이지 새로고침 없이 즉각적인 화면 전환이 가능하여 매끄럽고 앱과 같은 사용자 경험을 제공하는 것이 특징입니다 [1, 6-8].
## 📖 Core Content
* **작동 메커니즘**: CSR 환경에서 서버는 콘텐츠가 거의 없는 빈 HTML 파일과 JavaScript 코드를 클라이언트로 전송합니다 [1-3]. 브라우저는 이 JavaScript를 다운로드하고 파싱 및 실행한 뒤에야 필요한 데이터를 가져오고 [[DOM (Document Object Model)|DOM(Document Object Model]]을 생성하여 실제 화면에 시각적 콘텐츠를 렌더링합니다 [1, 2, 9].
* **주요 장점**:
* **풍부한 상호작용 및 UX**: 첫 페이지 로드 이후 후속 조작 시 서버에 전체 페이지를 다시 요청할 필요 없이 동적으로 필요한 데이터만 업데이트하므로, 전환이 매끄럽고 네이티브 앱과 같은 사용자 경험을 제공합니다 [1, 6-8].
* **서버 부하 및 호스팅 비용 감소**: 서버는 페이지 렌더링 연산을 수행하지 않고 정적 파일(HTML, CSS, JS)만 제공하면 되므로 리소스 부담이 적으며, Amazon S3나 Netlify와 같은 저렴한 정적 호스팅 서버를 활용할 수 있습니다 [6, 10].
* **빠른 개발 속도**: 개발자가 서버 측의 제약이나 호환성을 걱정하지 않고 `window` 객체와 같은 브라우저 전용 API를 자유롭게 활용할 수 있습니다 [10].
* **주요 한계 및 단점**:
* **초기 로딩 속도 저하**: 브라우저가 유의미한 콘텐츠를 표시하기 위해 전체 JavaScript 번들을 다운로드하고 실행할 때까지 기다려야 하므로 초기 렌더링(First Contentful Paint) 속도가 느립니다 [1, 6, 8, 9]. 이는 사용자의 기기 성능이나 네트워크 상태에 크게 의존합니다 [11].
* **검색 엔진 최적화(SEO) 제약**: 검색 엔진 크롤러나 소셜 미디어 봇이 웹사이트에 접근할 때 초기에는 빈 페이지만 보게 되므로, JavaScript를 제대로 파싱하지 못하면 콘텐츠 색인화 및 미리보기 생성이 누락될 수 있습니다 [1, 8, 9, 12, 13].
* **최적의 사용 사례(Use Cases)**: CSR은 SEO가 상대적으로 중요하지 않고, 사용자 상호작용과 실시간 데이터 업데이트가 필수적인 환경에 이상적입니다 [6, 14]. 로그인 장벽 뒤에 있는 대시보드, [[SaaS|SaaS]] 플랫폼, 내부 비즈니스 도구 및 소셜 미디어 플랫폼 등이 대표적인 적용 사례입니다 [2, 5, 14, 15].
## 🔗 Knowledge Connections
- **Related Topics:** `[[Server-Side Rendering (SSR)|Server-Side Rendering (SSR]]`, `Single-Page Applications (SPA)`, `[[Static Site Generation (SSG)|Static Site Generation (SSG]]`, `Document Object Model (DOM)`
- **Projects/Contexts:** `SaaS 플랫폼 및 대시보드 개발`, `React 기반 고도의 동적 웹 애플리케이션 구축`
- **Contradictions/Notes:** 소스 전반에서 CSR의 '뛰어난 상호작용성'과 'SEO 및 초기 로딩의 취약점'에 대한 평가는 일치하며 상충하는 내용은 없습니다 [1, 6, 8, 9, 12, 13]. 다만 최근에는 CSR의 한계를 극복하기 위해 [[Next.js|Next.js]]와 같은 프레임워크를 사용하여 페이지의 목적에 맞게 SSR이나 SSG를 혼합(하이브리드 렌더링)하여 사용하는 방식이 권장되고 있습니다 [15-17].
---
*Last updated: 2026-04-25*
@@ -1,22 +0,0 @@
# [[Component API Design|Component API Design]]
## 📌Brief 소목 Summary
컴포넌트 API 디자인(Component API Design)은 개발자가 UI 컴포넌트를 사용하고 구성하는 방식에 대한 구조적 설계와 인터페이스 정의를 의미합니다[1-3]. 잘 설계된 컴포넌트 API는 과도한 Prop 설정에 의존하는 대신 합성(Composition)을 활용하여 소비자가 유연하게 UI를 조립할 수 있도록 돕습니다[2, 4]. 이는 확장 가능하고 유지보수가 쉬운 재사용 가능한 React 컴포넌트 라이브러리를 구축하는 데 핵심적인 역할을 합니다[1, 5, 6].
## 📖 Core Content
* **Prop-Driven API의 한계**: 컴포넌트의 레이아웃과 동작을 오직 수많은 Prop(예: 다수의 불리언 플래그)으로만 제어하려 하면, 각 Prop이 결합되어 내부 로직이 복잡해지는 '블랙박스'가 형성됩니다[4, 7, 8]. 이는 예기치 않은 동작을 유발하고, 사소한 변경에도 시스템이 쉽게 깨지는 원인이 됩니다[4, 7].
* **명확한 계약(Explicit Contracts) 및 Prop 설계**: 좋은 컴포넌트 API는 직관적이고 오용하기 어려워야 합니다[3]. 구현 방식이 아닌 사용 목적(intent)에 따라 Prop 이름을 짓고, Prop의 수를 최소화하여 지나치게 복잡한 설정(Prop Soup)을 피해야 합니다[3, 9]. 또한 초기 사용을 위해 합리적인 기본값(Sensible Defaults)을 제공해야 합니다[3, 10].
* **합성 기반(Composition-Driven) 사고의 전환**: "컴포넌트가 어떻게 보여야 하는지"를 지시하는 대신, 상태와 규칙만 제공하고 "레이아웃은 소비자가 조립"하도록 구성하는 멘탈 모델로의 전환이 필요합니다[2].
* **확장 가능한 주요 API 패턴**:
* **복합 컴포넌트 ([[Compound Components|Compound Components]])**: `Accordion`, `Accordion.Item` 등과 같이 여러 하위 컴포넌트가 [[React Context|React Context]]를 통해 암시적으로 상태를 공유하는 패턴입니다[5, 11, 12]. 이 패턴은 Prop 드릴링을 방지하고 선언적이며 읽기 쉬운 구조를 제공합니다[5, 11].
* **[[Render Props|Render Props]]**: 사용자에게 특정 UI 렌더링에 대한 완전한 제어권을 넘겨주는 '탈출구(escape hatch)' 역할을 하며, 기존 API를 해치지 않으면서 고급 사용자에게 유연성을 제공합니다[13, 14].
* **오버라이드 패턴 ([[Overrides Pattern|Overrides Pattern]])**: Uber의 Base Web 등에서 활용되는 방식으로, `overrides` prop을 통해 컴포넌트 내부의 특정 하위 요소에 접근하여 속성, 스타일, 또는 렌더링 방식 전체를 대체할 수 있게 해줍니다[9, 15-17]. 이를 통해 모든 엣지 케이스를 위한 새로운 Prop을 추가할 필요가 없어집니다[17].
* **헤드리스 컴포넌트 ([[Headless Components|Headless Components]]) 및 슬롯 (Slots)**: UI 스타일링 없이 상태와 동작 로직만 제공하거나(Headless), 소비자가 자체 콘텐츠를 삽입할 수 있는 의도된 영역(Slots)을 제공하여 API의 복잡성을 낮추는 패턴입니다[8, 18].
## 🔗 Knowledge Connections
- **Related Topics:** [[Compound Components|Compound Components]], Headless Components, Overrides Pattern, [[Prop Drilling|Prop Drilling]], [[Atomic Design|Atomic Design]]
- **Projects/Contexts:** [[Uber Base Web|Uber Base Web]], Radix UI, [[Shopify Polaris|Shopify Polaris]]
- **Contradictions/Notes:** 복합 컴포넌트(Compound Components) 패턴은 강력한 구성의 자유도를 제공하지만, 지나친 자유로움으로 인해 사용자가 하위 컴포넌트의 순서를 임의로 변경하여 UX나 접근성의 일관성을 해칠 위험이 있습니다[19, 20]. 따라서 버튼이나 아이콘같이 단순하고 구조가 고정된 컴포넌트에서는 불필요한 추상화가 되므로 일반적인 Prop-Driven 방식이 더 안전하고 적합합니다[20, 21].
---
*Last updated: 2026-04-26*
@@ -1,20 +0,0 @@
# [[Component Library Architecture|Component Library Architecture]]
## 📌 Brief Summary
컴포넌트 라이브러리 아키텍처는 확장 가능하고 유지보수가 용이한 프론트엔드 애플리케이션을 구축하기 위해 재사용 가능한 UI 컴포넌트를 설계하고 조직화하는 구조적 접근 방식입니다 [1, 2]. 이는 단순한 시각적 요소를 넘어, 컴포넌트 간의 상태 공유, 로직 분리, 아키텍처 패턴을 활용하여 일관성 있는 시스템을 구현하는 것을 목표로 합니다 [3-5]. 잘 설계된 아키텍처는 과도한 상태 전달([[Prop Drilling|Prop Drilling]])을 방지하고 높은 유연성을 제공하여 끊임없이 변화하는 제품 요구사항에 안전하게 대처할 수 있게 합니다 [1, 6-8].
## 📖 Core Content
* **아토믹 디자인([[Atomic Design|Atomic Design]]) 방법론:** UI를 원자(Atoms), 분자(Molecules), 유기체(Organisms), 템플릿(Templates), 페이지(Pages) 등 5단계의 계층으로 나누어 구조화하는 멘탈 모델입니다 [2, 9, 10]. 이는 디자인 시스템의 일관성을 촉진하지만, 복잡한 비즈니스 로직과 결합될 때는 UI 라이브러리에만 아토믹 구조를 적용하고 애플리케이션 코드는 기능(Feature) 기반으로 분리하여 비즈니스 로직을 캡슐화하는 하이브리드 방식이 주로 권장됩니다 [11, 12].
* **복합 컴포넌트([[Compound Components|Compound Components]]) 패턴:** 탭(Tabs)이나 아코디언(Accordion)과 같이 밀접하게 연관된 하위 컴포넌트들이 [[React Context|React Context]]를 통해 암시적으로 상태를 공유하는 패턴입니다 [13-15]. 무수히 많은 Prop을 하위로 계속 넘겨주는 대신, 컴포넌트 소비자가 직접 하위 요소를 조합할 수 있게 하여 레이아웃의 유연성을 극대화하고 API를 깔끔하게 유지합니다 [3, 6, 16, 17].
* **헤드리스 컴포넌트([[Headless Components|Headless Components]]):** 접근성, 상태 관리, 비즈니스 로직 등 핵심 기능만 제공하고 시각적인 마크업과 스타일링은 전적으로 개발자에게 위임하는 방식입니다 [18, 19]. 주로 [[Tailwind CSS|Tailwind CSS]]와 결합하여 특정 프레임워크나 디자인 시스템에 종속되지 않는 고도로 맞춤화된 UI 라이브러리를 구축하는 데 사용됩니다 [18, 20].
* **오버라이드 패턴([[Overrides Pattern|Overrides Pattern]]):** Uber의 Base Web 시스템 등에서 활용하는 아키텍처로, 컴포넌트 내부의 모든 하위 요소에 접근할 수 있는 식별자를 제공하여 스타일, 속성, 혹은 렌더링되는 컴포넌트 자체를 통째로 교체할 수 있게 합니다 [21-24]. 이를 통해 모든 엣지 케이스마다 새로운 Prop을 추가하여 발생하는 복잡성(Prop soup)을 방지하고 심층적인 커스터마이징을 지원합니다 [23, 24].
* **기능 분할 설계([[Feature-Sliced Design|Feature-Sliced Design]], FSD) 및 모노레포:** 거대한 컴포넌트 라이브러리와 다수의 애플리케이션이 공존할 때, 단방향 의존성 흐름을 강제하는 구조입니다 [25-28]. Shared(공유 UI 기본 요소, 디자인 토큰 등), Entities, Features, Widgets, Pages 등의 계층으로 명확히 나누어 모노레포([[Turborepo|Turborepo]], Nx 등) 내에서 안정적이고 격리된 아키텍처를 유지할 수 있게 합니다 [27, 29-31].
* **디자인 토큰([[Design Tokens|Design Tokens]]) 계층화:** 색상, 타이포그래피, 간격 등의 원시 값을 추상화하여 기본 토큰(Primitives), 시맨틱 토큰(Semantic), 컴포넌트 토큰(Component Tokens)의 3단계 계층 구조로 관리합니다 [32-35]. 이는 테마(예: 다크 모드)의 동적 전환을 용이하게 하고 라이브러리 전반의 시각적 일관성과 안전한 리팩토링을 보장합니다 [5, 36-38].
## 🔗 Knowledge Connections
- **Related Topics:** [[Atomic Design|Atomic Design]], Compound Components, Headless Components, [[Design Tokens|Design Tokens]], [[Feature-Sliced Design|Feature-Sliced Design]]
- **Projects/Contexts:** [[Uber Base Web|Uber Base Web]], Shopify Polaris, React Server Components (RSC, Tailwind CSS vs [[Styled Components|Styled Components]]
- **Contradictions/Notes:** 복합 컴포넌트 패턴은 높은 유연성을 주지만 과용하면 소비자에게 너무 많은 통제권을 주어 UX나 접근성 등 구조적 일관성이 깨질 위험이 있습니다. 따라서 레이아웃이 고정되어 있는 단순한 버튼이나 배지 같은 컴포넌트에는 일반적인 Prop 기반 방식이 훨씬 적합합니다 [39-41]. 또한, 컴포넌트 스타일링 구현 시 Styled Components처럼 런타임에 스타일을 주입하는 방식은 동적 스타일링에 강력하나 [[Next.js 15|Next.js 15]]의 App Router 및 RSC 환경에서는 Context 부재로 인한 구조적 제약과 번들 사이즈 등 성능 비용이 따릅니다 [42-45]. 이 때문에 최신 프론트엔드 아키텍처는 정적 CSS 생성이 가능한 Tailwind CSS 또는 Zero-runtime 방식([[vanilla-extract|vanilla-extract]] 등)을 컴포넌트 라이브러리 구축에 더 권장하는 추세입니다 [46-49].
---
*Last updated: 2026-04-26*
@@ -1,30 +0,0 @@
# [[Component-Based Architecture (CBA)|Component-Based Architecture (CBA]]
## 📌 Brief Summary
컴포넌트 기반 아키텍처([[Component-Based Architecture|Component-Based Architecture]], CBA)는 독립적이고 모듈화된, 재사용 가능한 소프트웨어 컴포넌트들을 조립하여 애플리케이션을 구축하는 최신 소프트웨어 설계 패러다임입니다[1-3]. 레고 블록을 맞추듯 각 컴포넌트가 특정 기능을 수행하며, 명확히 정의된 인터페이스(API)를 통해 서로 통신합니다[2, 4]. 이 접근 방식은 소프트웨어를 처음부터 개발하는 대신 표준화된 부품을 재사용함으로써 유지보수성을 높이고 개발 속도를 앞당기며 뛰어난 확장성을 제공합니다[4-6].
## 📖 Core 소스 Content
* **컴포넌트의 정의 및 핵심 특징**
컴포넌트는 특정 기능을 캡슐화한 재사용 가능하고 독립적인 소프트웨어 단위입니다[7]. 주요 특징으로는 내부 구현과 데이터를 숨기고 필요한 인터페이스만 노출하는 **캡슐화(Encapsulation)**, 여러 언어나 플랫폼 간에도 표준 인터페이스를 통해 통신할 수 있는 **상호 운용성([[Interoperability|InterOperability]])**, 더 큰 시스템을 구성하기 위해 쉽게 플러그인 할 수 있는 **조립성(Composability)**, 그리고 기존 기능을 손상시키지 않고 교체할 수 있는 **대체 가능성(Replaceability)**이 있습니다[8-13].
* **컴포넌트 기반 개발의 주요 장점**
* **개발 속도 향상 및 비용 절감(Faster Time-to-Market):** 기존 컴포넌트를 재사용하여 반복적인 코딩을 방지함으로써 제품 출시를 가속화하고 개발 비용을 낮춥니다[14, 15].
* **확장성([[Scalability|Scalability]]):** 트래픽이나 요구사항이 증가할 때 시스템 전체가 아닌 장바구니, 결제 등 특정 컴포넌트만 개별적으로 추가 및 확장할 수 있습니다[16-18].
* **유지보수 및 병렬 개발(Maintainability & Collaboration):** 한 컴포넌트의 버그 수정이나 업데이트가 전체 시스템에 미치는 영향을 최소화합니다. 또한, 여러 팀이 서로 다른 컴포넌트(프론트엔드, 백엔드 등)를 동시에 개발할 수 있어 협업이 효율적입니다[14, 16, 18-20].
* **설계 원칙 및 구현 방법**
CBA 시스템을 구현할 때는 모듈성, 추상화, 그리고 역할에 따른 '관심사 분리([[_뇌와 팔다리의 분리_ - 관심사의 분리 (Separation of Concerns)|Separation of Concerns]])'를 원칙으로 삼아야 합니다[8, 21]. 시스템의 기능 및 비기능적 요구사항을 분석한 후 도메인 주도 설계(DDD) 등의 기법을 사용해 컴포넌트 경계를 식별합니다[22, 23]. 이후 명확한 API 및 통신 프로토콜(예: REST, gRPC 등)을 설계하고, 각각 독립적으로 개발 및 유닛 테스트를 진행한 뒤, CI/CD 파이프라인을 통해 통합 및 배포를 수행합니다[24-26].
* **구현 시 직면하는 한계 및 과제**
* **초기 설계의 복잡성과 통합 오버헤드:** 시스템을 모듈화하고 인터페이스와 의존성을 명확히 정의하는 초기 계획 단계가 까다롭습니다[27-29]. 서로 다른 팀이 개발한 컴포넌트 간의 통신과 매끄러운 통합을 보장하는 것에도 오버헤드가 발생합니다[29, 30].
* **성능 저하 및 의존성 관리:** 네트워크 호출이나 프로세스 간 통신 등 컴포넌트 상호작용으로 인해 성능 오버헤드와 지연(Latency)이 발생할 수 있습니다[27, 30, 31]. 또한, 다수의 컴포넌트가 다양한 버전의 라이브러리에 의존할 경우 버전 충돌 및 관리가 매우 복잡해집니다[31, 32].
* **보안 및 과잉 엔지니어링 위험:** 각 컴포넌트의 업데이트 주기가 달라 최신화되지 않은 컴포넌트가 전체 시스템의 보안 취약점이 될 수 있으며[33], 유연성만을 추구하다 보면 시스템을 너무 잘게 쪼개어 과잉 엔지니어링(Over-engineering)으로 이어질 위험도 존재합니다[34].
## 🔗 Knowledge Connections
- **Related Topics:** Microservices Architecture, Service-Oriented Architecture (SOA), Monolithic Architecture, Object-Oriented Architecture
- **Projects/Contexts:** React, Angular, Vue.js, PayPal, Spotify, Uber, Walmart
- **Contradictions/Notes:** 소스에 따르면, 객체 지향 아키텍처(Object-Oriented Architecture)와 CBA는 원칙을 일부 공유하지만 차이가 있습니다. 객체 지향 아키텍처가 단일 애플리케이션 내에서 데이터와 동작을 캡슐화하는 데 중점을 둔다면, CBA는 여러 시스템 및 애플리케이션 전반에서 상호작용하고 재사용할 수 있는 독립적인 단위 생성을 강조합니다[35]. 또한 기존의 모놀리식 아키텍처(Monolithic Architecture)는 시스템 전체를 하나의 코드베이스로 묶어 확장 및 유지보수가 어렵지만, CBA는 느슨하게 결합된 모듈을 통해 독립적인 배포와 병렬 개발을 가능하게 합니다[36, 37].
---
*Last updated: 2026-04-25*
@@ -1,32 +0,0 @@
# [[Component-Based Architecture|Component-Based Architecture]]
## 📌 Brief Summary
컴포넌트 기반 아키텍처(Component-Based [[Architecture|Architecture]], CBA)는 소프트웨어 시스템을 모듈화되고 독립적이며 재사용 가능한 단위인 '컴포넌트(Component)'로 나누어 구축하는 설계 방법론입니다 [1, 2]. 레고 블록을 조립하듯 각 컴포넌트를 결합하여 크고 복잡한 애플리케이션을 완성할 수 있으며, 이로 인해 개발 속도와 시스템 확장성을 크게 향상시킵니다 [3, 4]. 각 컴포넌트는 내부 로직과 상태를 캡슐화하고 명확히 정의된 인터페이스를 통해서만 상호작용하도록 설계되어, 유지보수성과 팀 간의 협업 효율을 극대화합니다 [5, 6].
## 📖 Core Content
- **핵심 원칙 및 특징:**
- **모듈성 및 캡슐화 ([[Modularity|Modularity]] & Encapsulation):** 컴포넌트는 특정한 목적을 위해 기능과 데이터를 내부로 숨기고(캡슐화), 외부에 필요한 부분만 잘 정의된 인터페이스로 노출합니다 [5, 7].
- **재사용성 및 독립성 (Reusability & Independence):** 한 번 개발된 컴포넌트는 수정 없이 여러 프로젝트에 재사용될 수 있으며, 전체 시스템을 파괴하지 않고 독립적으로 개발, 테스트, 배포 및 교체가 가능합니다 [8-10].
- **상호운용성 ([[Interoperability|InterOperability]]):** 서로 다른 기술이나 플랫폼으로 구축된 컴포넌트라도 표준화된 인터페이스와 API를 통해 원활하게 통신하고 결합될 수 있습니다 [6, 11].
- **아키텍처의 주요 이점:**
- **개발 속도 향상 및 비용 절감:** 기존 컴포넌트를 재사용하여 코드를 처음부터 다시 작성하는 수고를 덜어 제품 출시 기간(Time-to-Market)을 앞당깁니다 [12, 13].
- **확장성 및 유지보수 용이성:** 전체 시스템을 재구성할 필요 없이 트래픽이나 요구사항에 따라 특정 컴포넌트만 독립적으로 확장하거나 업그레이드할 수 있으며, 버그 수정 시 다른 시스템에 미치는 영향을 최소화합니다 [8, 14-16].
- **병렬 개발 (Parallel Development):** 시스템이 명확하게 나뉘어 있어 여러 개발 팀이 동시에 각기 다른 컴포넌트를 분담하여 작업할 수 있습니다 [8, 17].
- **설계 시 당면 과제 및 단점:**
- **복잡성 및 의존성 관리:** 컴포넌트의 수가 증가할수록 컴포넌트 간의 상호작용, 호환성, 버전 관리 등 의존성을 통제하고 통합하는 것이 복잡해집니다 [18-20].
- **성능 오버헤드:** 시스템을 지나치게 작은 컴포넌트로 나눌 경우(Over-engineering), 컴포넌트 간 통신(네트워크 호출 및 RPC 등)으로 인한 지연(Latency)과 오버헤드가 발생하여 성능을 저하시킬 수 있습니다 [18, 21, 22].
- **보안 관리의 어려움:** 각 컴포넌트가 각기 다른 라이브러리와 업데이트 주기를 가질 경우, 제때 업데이트되지 않은 구식 컴포넌트가 전체 애플리케이션의 보안 취약점이 될 위험이 존재합니다 [23].
- **실제 활용 및 대안 아키텍처:**
- **활용 사례:** 사용자 로그인, 결제 게이트웨이, 쇼핑카트와 같은 모듈이 독립적으로 필요한 전자상거래 플랫폼, CRM 시스템, 모바일 앱 등에서 활발히 사용됩니다 [24, 25]. 프론트엔드 라이브러리(React, Angular, Vue.js)뿐만 아니라 백엔드 플랫폼(Java EE, .NET 등)에서도 이 방식을 채택하며, PayPal, Walmart, Spotify, Uber 등의 기업들이 이 아키텍처를 도입해 확장성을 입증했습니다 [3, 26, 27].
- **대안 아키텍처:** 프로젝트의 규모와 팀 구조에 따라 하나의 코드베이스로 구성된 Monolithic Architecture, 서비스 단위로 결합도를 낮춘 Microservices Architecture, 기업 환경에 맞춘 Service-Oriented Architecture (SOA), Layered Architecture 등과 비교되거나 혼합되어 사용됩니다 [28-31].
## 🔗 Knowledge Connections
- **Related Topics:** [[Modularity|Modularity]], Encapsulation, Monolithic Architecture, Microservices Architecture, Service-Oriented Architecture (SOA)
- **Projects/Contexts:** React, Angular, Vue.js 기반 프론트엔드 UI 구축, 전자상거래 플랫폼 및 CRM 시스템 설계, Java EE 및 .NET 엔터프라이즈 애플리케이션
- **Contradictions/Notes:** 컴포넌트 기반 아키텍처는 유연성과 재사용성을 극대화하지만, 모듈화를 극대화하려는 목적으로 시스템을 너무 잘게 쪼개는 것(Over-engineering)은 오히려 통합 비용과 통신 오버헤드를 발생시키고 디버깅을 어렵게 만들 수 있으므로 적절한 세분화(Granularity) 수준을 결정하는 것이 핵심입니다 [18, 22, 32].
---
*Last updated: 2026-04-25*
@@ -1,23 +0,0 @@
# [[Component-Based Design|Component-Based Design]]
## 📌 Brief Summary
컴포넌트 기반 디자인(Component-Based Design)은 사용자 인터페이스를 재사용 가능하고 이식성이 뛰어나며 예측 가능한 모듈식 구성 요소로 구축하는 아키텍처 접근 방식입니다 [1, 2]. 이는 거대한 단일 컴포넌트를 구성하는 방식에서 벗어나, 조합(Composition)을 통해 레이아웃과 동작을 조립함으로써 '프롭 드릴링([[Prop Drilling|Prop Drilling]])'과 숨겨진 결합도를 줄입니다 [3-5]. 단일 책임 원칙과 명시적인 API 계약을 준수함으로써, 변화하는 요구사항에 유연하게 적응하고 확장할 수 있는 확장성 높은 UI 시스템을 구축하는 데 핵심적인 역할을 합니다 [6-8].
## 📖 Core Content
- **원자적 설계([[Atomic Design|Atomic Design]]) 계층 구조**: 사용자 인터페이스는 더 이상 분해할 수 없는 기본 요소인 원자(Atoms), 이들이 모인 분자(Molecules), 더 복잡한 유기체(Organisms), 구조를 정의하는 템플릿(Templates), 그리고 실제 콘텐츠가 채워지는 페이지(Pages)의 5단계로 체계화하여 설계할 수 있습니다 [9-12].
- **재사용성을 위한 핵심 원칙**: 훌륭한 재사용 가능 컴포넌트는 단일 책임(Single Responsibility) 원칙을 따르고, 상속보다는 조합(Composition)을 우선하며, 명확한 API 계약을 가져야 합니다 [8]. 내부 상태를 최소화하여 예측 가능성을 높이고, 접근성([[Accessibility|Accessibility]])을 기본적으로 내장해야 합니다 [8, 13].
- **프롭(Prop) 기반에서 조합(Composition) 기반 API로의 전환**: 모든 구성 옵션을 프롭으로 전달하는 방식은 컴포넌트를 변경하기 어려운 '블랙 박스'로 만들며 기하급수적인 복잡성을 초래합니다 [14-16]. 대신, 책임을 분산시켜 사용자가 필요에 따라 하위 요소를 조립하게 하는 조합 기반 접근 방식이 대규모 UI 확장에 유리합니다 [3, 5].
- **확장 가능한 컴포넌트 패턴**:
- **복합 컴포넌트([[Compound Components|Compound Components]])**: React 컨텍스트를 활용하여 탭(Tabs)이나 아코디언(Accordion)과 같은 여러 컴포넌트가 암시적으로 상태를 공유하는 패턴으로, 프롭 비대화 없이 높은 레이아웃 조립 유연성을 제공합니다 [4, 16-18].
- **헤드리스 컴포넌트([[Headless Components|Headless Components]])**: 복잡한 상태 관리와 논리만 캡슐화하고 UI 마크업과 스타일링은 온전히 소비자에게 위임하여, 특정 디자인 시스템에 구애받지 않는 유연성을 제공합니다 [16, 19, 20].
- **렌더 프롭([[Render Props|Render Props]])**: 렌더링 함수를 자식이나 프롭으로 전달하여 논리를 공유하는 기법으로, 사용자에게 렌더링 결과에 대한 완전한 제어권을 줍니다 [16, 20, 21].
- **오버라이드 패턴([[Overrides Pattern|Overrides Pattern]])**: 컴포넌트 내부의 하위 요소에 대한 식별자를 노출하여, 매번 새로운 프롭을 추가할 필요 없이 특정 내부 요소의 스타일이나 하위 컴포넌트를 깊게 커스터마이징할 수 있게 합니다 [16, 22, 23].
- **디자인 토큰([[Design Tokens|Design Tokens]]) 바인딩**: 컴포넌트는 하드코딩된 리터럴 값(예: `#dc2222`)을 피하고 디자인 토큰(예: `color.error`)을 참조하여 바인딩해야 합니다 [24, 25]. 이를 통해 간격, 색상, 타이포그래피 등의 디자인 요소가 변경될 때 시스템 전체에 일관된 업데이트가 자동으로 반영됩니다 [24].
## 🔗 Knowledge Connections
- **Related Topics:** [[Atomic Design|Atomic Design]], Compound Components, Headless Components, [[Design Tokens|Design Tokens]], [[Feature-Sliced Design|Feature-Sliced Design]]
- **Projects/Contexts:** [[Uber Base Web|Uber Base Web]], Shopify Polaris, [[Radix UI|Radix UI]]
- **Contradictions/Notes:** 원자적 설계(Atomic Design)는 시각적 일관성을 유지하는 데 효과적이지만, 복잡한 비즈니스 로직을 포함하는 컴포넌트를 엄격한 범주에 억지로 맞출 때 구조적 한계에 부딪힐 수 있으므로 실무에서는 기능(Feature) 기반 구조와 결합하여 사용하는 것이 권장됩니다 [26, 27]. 또한, 복합 컴포넌트 패턴은 소비자에게 막강한 유연성을 제공하지만, 너무 많은 자유를 허용하면 일관된 UI나 접근성이 훼손될 수 있으므로 디자인 시스템 차원에서 안전한 구성 경계(composition [[Boundaries|Boundaries]])를 문서화하는 것이 필수적입니다 [28, 29].
---
*Last updated: 2026-04-26*
@@ -1,23 +0,0 @@
# [[Compound Components Pattern|Compound Components Pattern]]
## 📌 Brief Summary
[[Compound Components|Compound Components]] 패턴은 암시적으로 상태를 공유하고 특정 부모 내에서만 작동하는 일련의 관련 컴포넌트들을 노출하여 선언적이고 가독성 높은 API를 구성하는 React 컴포넌트 설계 방식이다 [1]. 모든 기능을 수십 개의 prop으로 단일 컴포넌트에 쑤셔넣는 대신, 여러 협력 컴포넌트에 책임을 분산시켜 복잡한 요구사항을 처리한다 [2]. 이는 HTML의 `<select>``<option>` 요소처럼 개별적인 책임을 유지하면서도 응집력 있는 단위로 함께 작동하여, 재사용 가능하고 유연한 UI를 구축하는 데 핵심적인 역할을 한다 [1, 3].
## 📖 Core Content
* **작동 원리 및 상태 관리:** 이 패턴은 [[React Context|React Context]]를 내부 계약(Internal Contract)으로 사용하여 [[Prop Drilling|Prop Drilling]] 없이 컴포넌트 간에 상태를 공유한다 [1, 4, 5]. 최상위(Root) 컴포넌트인 Provider는 전역 상태를 소유 및 관리하며, 하위 컴포넌트(Header, Body 등)는 전체 상태를 알 필요 없이 자신에게 필요한 좁은 범위의 상태만 소비하도록 설계된다 [6-8].
* **주요 장점:**
* 컴포넌트의 레이아웃과 구성을 소비자가 자유롭게 결정할 수 있는 높은 유연성을 제공한다 [3, 9].
* 복잡한 기능을 구현할 때 수많은 설정 prop으로 인해 발생하는 'Prop Soup(프롭 수프)' 문제와 내부 로직이 숨겨지는 '블랙 박스' 문제를 해결하여 명확한 API를 유지할 수 있다 [10-12].
* 디자인 시스템 구축 시 확장성이 뛰어나며, `aria-controls`와 같은 접근성(A11y) 속성을 수동으로 전달할 필요 없이 내부적으로 자동 연결하여 관리를 단순화할 수 있다 [13].
* **단점 및 주의사항:**
* 초기 작성해야 하는 보일러플레이트 코드량이 많고, 로직이 Context나 Hook에 분산되어 있어 단순 prop 기반 컴포넌트보다 버그 추적 및 디버깅이 어려울 수 있다 [13, 14].
* 컴포넌트의 순서를 바꾸거나 생략할 수 있는 등 소비자에게 주어지는 자유도가 너무 높으면 오히려 UX나 접근성 일관성이 깨질 위험이 있어 명확한 문서화가 필수적이다 [14, 15].
* **적용 시기:** 레이아웃이 다양하게 변하거나, 소비자가 구성을 자유롭게 조합해야 할 때, 혹은 확장 가능한 공유 UI 라이브러리를 구축할 때 매우 적합하다 [15]. 하지만 Button, Icon, Badge처럼 단일하고 고정된 레이아웃을 가진 단순한 컴포넌트에는 불필요한 추상화를 초래하므로 피해야 한다 [16].
## 🔗 Knowledge Connections
- **Related Topics:** [[React Context API|React Context API]], Headless Components, Render Props, [[Atomic Design|Atomic Design]]
- **Projects/Contexts:** [[Radix UI|Radix UI]], Headless UI, [[React Design Systems|React DesignSystems]]
- **Contradictions/Notes:** Compound Components는 구성의 유연성을 제공하여 재사용성을 높이지만, 너무 많은 자유도를 제공하면 일관성을 해치고 접근성을 손상시킬 수 있으므로 디자인 시스템 차원에서 "안전한 구성 경계(safe composition [[Boundaries|Boundaries]])"를 명확히 정의하고 문서화해야 한다 [14, 15]. 또한 모든 컴포넌트에 이 패턴을 남용하는 것은 가장 흔한 실수이며, 레이아웃이 고정된 단순 컴포넌트는 일반적인 Prop 기반 접근이 더 안전하고 단순하다고 조언한다 [16].
---
*Last updated: 2026-04-26*
@@ -1,34 +0,0 @@
# [[Compound Components|Compound Components]]
## 📌Brief 단기 요약
합성 컴포넌트(Compound Components)는 여러 개의 연관된 하위 컴포넌트들이 암시적으로 상태를 공유하며 하나의 응집력 있는 단위로 동작하도록 설계하는 React 컴포넌트 패턴입니다 [1, 2]. 단일 컴포넌트에 수십 개의 Prop을 밀어 넣어 비대해지는 것을 방지하고, 기능과 책임을 여러 컴포넌트에 분산시킵니다 [3, 4]. 이는 HTML의 `<select>``<option>` 태그처럼 직관적이고 선언적인 API를 형성하여 뛰어난 유연성과 재사용성을 제공합니다 [1, 4].
## 📖 Core Content
* **설계 철학 및 멘탈 모델의 전환**
* 기존의 Prop 기반(Prop-Driven) API는 요구사항(레이아웃 변경, 조건부 동작 등)이 추가될 때마다 Prop이 폭발적으로 증가하여 유지보수가 어렵고 컴포넌트 내부가 파악하기 힘든 '블랙박스'가 되는 문제가 있습니다 [5-7].
* 합성 컴포넌트는 이를 '구성 중심(Composition-Driven)' 모델로 전환하여, 컴포넌트는 상태와 규칙만 관리하고 레이아웃과 구조의 결정권은 이를 사용하는 소비자(Consumer)에게 일임합니다 [7, 8].
* **[[React Context|React Context]]를 활용한 암시적 상태 공유**
* 이 패턴의 핵심 기술은 React Context를 내부 상태 관리의 '계약(Contract)'으로 사용하는 것입니다 [9]. 부모(Root) 컴포넌트가 Context를 통해 상태를 제공하고, 하위 컴포넌트들은 [[Prop Drilling|Prop Drilling]] 없이 필요한 상태만 구독하여 동작합니다 [1, 10].
* 내부 구현이 추상화되어 있으므로, 소비자는 내부가 어떻게 작동하는지 몰라도 하위 컴포넌트들을 자유롭게 조립할 수 있습니다 [9].
* **주요 장점**
* **뛰어난 유연성과 가독성:** 특정 기능을 쉽게 포함하거나 제외할 수 있으며, 개발자는 하위 요소의 렌더링 순서와 구조를 자유롭게 재배치할 수 있습니다 [4, 7, 8].
* **접근성(A11y) 자동화:** 컴포넌트 내부 Context에서 상태와 ID를 제어하므로, `aria-controls``aria-labelledby` 같은 접근성 속성을 소비자가 수동으로 연결할 필요 없이 자동으로 처리할 수 있습니다 [11].
* **성능 최적화 기법**
* 복잡한 시스템이나 대규모 렌더링이 필요한 경우, 불필요한 리렌더링을 방지하기 위해 빈번하게 변경되는 상태와 정적인 구성을 각각 다른 Context로 분리(Split Contexts)하여 최적화할 수 있습니다 [12, 13].
* 필요한 곳에만 하위 컴포넌트를 전략적으로 메모이제이션(Memoization)하여 성능을 유지합니다 [14].
* **사용 시 주의사항 및 한계**
* 패턴을 구현하기 위해 초기에 작성해야 할 코드가 많아지고, Context 기반 렌더링 비용이 발생하며, 디버깅이 다소 까다로워질 수 있습니다 [11].
* 버튼, 배지, 아바타, 아이콘처럼 구조가 단일하고 레이아웃이 고정된 컴포넌트에는 불필요한 추상화(Overusing)가 될 수 있으므로 피해야 합니다 [15, 16]. 탭, 아코디언, 모달, 드롭다운과 같이 레이아웃과 조립 방식이 다양한 복잡한 UI에 가장 적합합니다 [17-19].
## 🔗 Knowledge Connections
- **Related Topics:** [[Render Props|Render Props]], Headless Components, Context API, [[Atomic Design|Atomic Design]]
- **Projects/Contexts:** [[Radix UI|Radix UI]], Headless UI, [[MUI|MUI]]
- **Contradictions/Notes:** 합성 컴포넌트는 매우 유연하고 강력한 패턴이지만, 하위 컴포넌트의 구성을 소비자가 자유롭게 바꿀 수 있기 때문에 의도치 않게 접근성이나 일관된 UX를 해칠 수 있습니다. 따라서 디자인 시스템에서는 안전한 조합의 경계(Safe composition [[Boundaries|Boundaries]])를 정의하고 문서화하는 것이 필수적입니다 [15, 17]. 또한 단순하고 고정된 레이아웃을 가진 컴포넌트에서는 일반적인 Prop 기반 접근법이 훨씬 간단하고 안전합니다 [16].
---
*Last updated: 2026-04-26*
@@ -1,23 +0,0 @@
# [[Concurrent Rendering|Concurrent Rendering]]
## 📌 Brief Summary
Concurrent Rendering(동시성 렌더링)은 메인 스레드를 블로킹하지 않고 UI의 여러 부분을 병렬로 렌더링할 수 있게 해주는 React의 핵심 아키텍처 기능입니다 [1]. 렌더링 작업을 '[[Time Slicing|Time Slicing]](시간 분할)'을 통해 작은 단위로 쪼개고 중요도에 따라 우선순위를 부여하여, 긴급한 사용자 입력에 반응하기 위해 렌더링을 일시 중지하거나 재개할 수 있습니다 [1, 2]. 이를 통해 무거운 연산 중에도 UI가 멈추지 않고 즉각적으로 반응하도록 하여 애플리케이션의 체감 성능을 극대화합니다 [3, 4].
## 📖 Core Content
* **Fiber 아키텍처와 Work Loop**
Concurrent Rendering은 React 16에서 처음 도입된 Fiber 아키텍처를 기반으로 작동합니다 [5, 6]. 기존의 단일 재귀 호출 기반 동기식 렌더링과 달리, 렌더링 작업을 'Fiber 노드'라는 작은 작업 단위(Unit of Work)로 분할합니다 [2, 7]. React는 Work Loop를 통해 이 트리를 점진적으로 순회하며, 각 작업 단위가 끝날 때마다 브라우저에 제어권을 양보(yield)하여 클릭과 같은 고우선순위 상호작용을 처리할 수 있는지 확인합니다 [8, 9].
* **우선순위 기반 스케줄링 ([[Lane Model|Lane Model]])**
동시성 작업의 우선순위는 'Lane'이라는 비트마스크 시스템을 통해 체계적으로 관리됩니다 [10, 11]. 타이핑이나 클릭처럼 사용자가 즉각적인 반응을 기대하는 긴급한 업데이트(Sync Lane)는 최우선으로 즉시 처리되며, 스크롤(InputContinuous Lane), 네트워크 응답(Default Lane), 백그라운드 렌더링(Idle Lane) 등은 각각 낮은 우선순위를 부여받아 스케줄링됩니다 [12-14]. 이 과정에서 렌더링 단계(Render phase)는 중단 가능(Interruptible)하므로, 더 높은 우선순위의 작업이 도착하면 기존의 렌더링 작업을 일시 중지, 폐기 또는 재시작할 수 있습니다 [15, 16].
* **Concurrent Hooks 활용 (`[[useTransition|useTransition]]`, `[[useDeferredValue|useDeferredValue]]`)**
[[React 18|React 18]] 및 19에서는 개발자가 동시성 렌더링을 직접 제어할 수 있는 훅을 제공합니다 [17, 18]. **`useTransition`**은 개발자가 상태 업데이트를 직접 긴급하지 않은 것(low-priority)으로 지정하여, 수천 개의 데이터 필터링 연산이 백그라운드에서 도는 중에도 사용자의 타이핑 입력이 즉시 반영되도록 돕습니다 [17, 19, 20]. **`useDeferredValue`**는 외부에서 전달받는 값 자체의 렌더링을 지연시켜, 새로운 결과가 준비될 때까지 UI가 동결되는 것을 막고 이전 결과를 표시하게 해줍니다 [19, 21].
* **성능 최적화 메커니즘 (체감 성능 향상)**
Concurrent Rendering의 핵심은 코드의 실제 연산 속도를 물리적으로 가속하는 것이 아닙니다 [3]. 무거운 연산이 즉각적인 사용자 피드백을 방해하지 않도록 처리 순서를 최적화하여 앱이 **"더 빠르게 느껴지게(feel faster)"** 만드는 데 목적이 있습니다 [3]. 이러한 비차단형(Non-[[Blocking|Blocking]]) 렌더링 방식은 사용자의 입력이 다음 화면 페인트로 이어지는 속도를 측정하는 핵심 웹 지표인 **INP(Interaction to Next Paint)**를 향상시키는 데 직접적으로 기여합니다 [21, 22].
## 🔗 Knowledge Connections
- **Related Topics:** `[[Fiber Architecture|Fiber Architecture]]`, `Time Slicing`, `Lane Model`, `[[useTransition|useTransition]]`, `[[useDeferredValue|useDeferredValue]]`
- **Projects/Contexts:** `[[React 18 & 19 Performance Optimization|React 18 & 19 Performance Optimization]]`
- **Contradictions/Notes:** 소스에 따르면 `useTransition``useDeferredValue`와 같은 동시성 훅은 코드 자체의 속도를 높여주지는 않지만, 무거운 연산이 사용자 피드백을 방해하지 않도록 스케줄링하여 앱의 "체감 성능"을 개선하는 방식으로 작동한다는 점을 명확히 하고 있습니다 [3].
---
*Last updated: 2026-04-25*
@@ -1,25 +0,0 @@
# [[Container Queries|Container Queries]]
## 📌 Brief Summary
Container Queries(컨테이너 쿼리)는 브라우저 창(뷰포트) 전체 크기가 아닌, 컴포넌트가 속한 부모 컨테이너의 가용 너비에 따라 요소의 스타일을 유동적으로 조정할 수 있게 해주는 최신 CSS 기능입니다 [1, 2]. 이는 기존 미디어 쿼리의 한계를 극복하여 페이지 중심에서 컴포넌트 중심의 반응형 설계로 패러다임을 전환시켰습니다 [1, 3]. 디자인 시스템 및 모듈식 아키텍처와 완벽하게 결합하여, 다양한 문맥(Context)에서 독립적으로 재사용할 수 있는 유지보수성 높은 UI를 구축하는 데 핵심적인 역할을 합니다 [1, 4, 5].
## 📖 Core 소스 Content
- **기존 미디어 쿼리의 한계와 도입 배경:**
기존의 뷰포트 기반 미디어 쿼리(Media Queries)는 브라우저 창의 크기에만 반응하는 근본적인 한계가 있었습니다 [1]. 이로 인해 좁은 사이드바에 위치한 카드와 전체 너비의 히어로 섹션에 위치한 카드가 동일한 뷰포트 너비 기준을 공유하여 스타일링에 어려움이 있었습니다 [1, 5]. 컨테이너 쿼리는 컴포넌트가 부모 요소의 크기를 기준으로 스스로 프레젠테이션을 결정하게 하여 이러한 문제를 해결합니다 [1, 6].
- **구현 방식 및 문법:**
컨테이너 쿼리를 사용하려면 먼저 부모 요소에 `container-type: inline-size;` 속성을 정의하여 컨테이너로 지정해야 합니다 [4, 5]. 그 후 `@container (min-width: 600px)`와 같은 조건문을 사용하여 해당 컨테이너 크기에 도달했을 때 자식 요소(예: 카드 레이아웃의 컬럼 변경)의 스타일을 변경합니다 [1, 2, 4]. 또한, `cqi``cqw`와 같은 컨테이너 인라인 크기 기준의 상대 단위를 사용하여 타이포그래피나 여백을 유동적으로 제어할 수 있습니다 [7-9].
- **설계 패러다임의 변화:**
컨테이너 쿼리의 도입으로 반응형 디자인의 철학이 '뷰포트 중심(Viewport-centric)'에서 '컴포넌트 중심(Component-centric)'으로 이동했습니다 [3]. 이 접근 방식은 컴포넌트가 독립적이고 문맥을 인식(context-aware)할 수 있게 만들어 주어, 복잡한 대규모 애플리케이션의 여러 부분에서 컴포넌트를 재사용할 때의 복원력(resilient)을 높여줍니다 [1, 5]. 이는 독립적인 UI 단위로 구성되는 최신 디자인 시스템의 구조와 완벽하게 일치합니다 [1, 5].
- **실무 활용과 업계 표준:**
2024년 이후 모든 최신 브라우저에서 완벽히 지원되며, 2026년 기준으로는 고급 기술을 넘어 컴포넌트 수준의 반응형 디자인을 위한 기본 표준(Default practice)으로 자리 잡았습니다 [10, 11]. 특히 데이터가 많은 [[SaaS|SaaS]] 대시보드나 이커머스에서 좁은 너비일 때 차트를 단순한 숫자 카드로 변환하거나, 데이터 테이블을 카드 스택으로 바꾸는 등의 복잡한 레이아웃 처리에 탁월하게 활용됩니다 [4, 12].
## 🔗 Knowledge Connections
- **Related Topics:** [[Responsive Web Design|Responsive Web Design]], Media Queries, DesignSystems, [[Fluid Typography|Fluid Typography]]
- **Projects/Contexts:** SaaS 대시보드 레이아웃 설계, [[컴포넌트 기반 아키텍처(Component-Based Architecture)|컴포넌트 기반 아키텍처(Component-Based Architecture]]
- **Contradictions/Notes:** 소스에서는 컨테이너 쿼리를 뷰포트 기반 미디어 쿼리의 한계를 극복하는 필수적인 대체재 및 보완재로 설명하며, 모듈식 설계와 유지보수성 측면에서 2026년 기준 반응형 CSS 설계의 가장 중요한 표준으로 강조하고 있습니다 [1, 3, 11].
---
*Last updated: 2026-04-26*
@@ -1,18 +0,0 @@
# [[Context API|Context API]]
## 📌 Brief Summary
Context API는 React에서 프롭 드릴링([[Prop Drilling|Prop Drilling]]) 없이 하위 컴포넌트가 공유 데이터나 상태를 직접 소비할 수 있게 해주는 기능이다 [1], [2]. 이는 `styled-components``ThemeProvider`와 같은 테마 적용 기능이나, 상태를 암시적으로 공유하는 합성 컴포넌트(Compound Components) 패턴을 구축하는 데 핵심적으로 사용된다 [3], [4]. 하지만 최근의 [[React Server Components|React Server Components]](RSC) 아키텍처에서는 서버에 Context 환경이 존재하지 않기 때문에 런타임 [[CSS-in-JS|CSS-in-JS]] 라이브러리 등과 함께 사용할 때 근본적으로 호환되지 않는 한계를 지닌다 [5], [6].
## 📖 Core Content
* **합성 컴포넌트(Compound Components)의 내부 규약:** Context API는 컴포넌트의 내부 상태를 외부로 노출하지 않으면서도 관련된 하위 컴포넌트들 간에 상태를 공유하기 위한 내부 규약(Internal Contract)으로 자주 활용된다 [7], [8]. 소비자(Consumer)가 글로벌 상태를 직접 관리할 필요 없이, 자식 컴포넌트들이 프롭 드릴링 없이 공유 상태에 접근하여 유연하고 응집력 있는 UI를 구성할 수 있도록 돕는다 [2].
* **테마 및 전역 스타일 관리:** `styled-components`와 같은 CSS-in-JS 라이브러리에서 `ThemeProvider`는 Context API를 통해 컴포넌트 트리 하위에 있는 모든 컴포넌트에 테마 객체를 주입한다 [3]. 컴포넌트 트리 내부에서 동적 테마 접근을 가능하게 하는 `ThemeConsumer` 역시 `React.createContext`를 기반으로 만들어졌다 [9].
* **성능 최적화와 리렌더링 관리:** Context의 상태가 변경되면 해당 Context를 소비하는 모든 하위 컴포넌트가 리렌더링된다 [10]. 따라서 복잡하거나 재사용성이 높은 UI 컴포넌트를 구축할 때는 불필요한 리렌더링을 방지하기 위해 자주 변경되는 상태의 Context와 정적인 구성(Configuration)을 담당하는 Context를 분리(Split Contexts)하여 관리하는 것이 성능 최적화 기법으로 권장된다 [10], [11].
* **React [[Server Components|Server Components]](RSC) 환경에서의 한계:** Next.js App Router와 같은 서버 컴포넌트 실행 환경에서는 브라우저의 React Context를 사용할 수 없다 [5], [6]. 이로 인해 Context 기반의 테마를 사용하는 `styled-components``Emotion` 같은 라이브러리는 RSC에서 `ThemeProvider`가 아무 기능도 하지 못하게 되며(no-op) [3], [12], 대신 CSS 사용자 지정 속성([[CSS Variables|CSS Variables]])을 활용하거나 빌드 타임에 정적 CSS를 생성하는 방식(Zero-runtime)으로 전환해야 한다 [13], [5], [12].
## 🔗 Knowledge Connections
- **Related Topics:** [[Compound Components|Compound Components]], React Server Components (RSC), Prop Drilling, [[Styled Components|Styled Components]]
- **Projects/Contexts:** [[Next.js App Router|Next.js App Router]], [[Shopify Polaris|Shopify Polaris]]
- **Contradictions/Notes:** 기존 CSS-in-JS 생태계에서는 동적 테마 제공을 위해 Context API에 전적으로 의존했으나, React Server Components(RSC) 환경에서는 서버에 Context가 존재하지 않는다는 모순이 발생하여 CSS-in-JS가 RSC와 근본적으로 호환되지 않는 문제를 낳았으며, 이에 따라 CSS 변수를 사용하는 방식으로 설계 방향이 이동하고 있다 [3], [5], [6], [12].
---
*Last updated: 2026-04-26*
@@ -1,31 +0,0 @@
# [[Core Web Vitals Optimization (INP, LCP 개선)|Core Web Vitals Optimization (INP, LCP 개선]]
## 📌 Brief Summary
[[Core Web Vitals|Core Web Vitals]]는 구글이 웹 페이지의 검색 순위와 사용자 경험을 평가하기 위해 정의한 핵심 성능 지표입니다 [1]. 여기에는 화면의 주요 콘텐츠가 로드되는 속도를 측정하는 LCP(Largest Contentful Paint)와 페이지 세션 내내 애플리케이션이 사용자 상호작용에 얼마나 빠르게 응답하는지 측정하는 INP(Interaction to Next Paint)가 포함됩니다 [1, 2]. 이 지표들의 기준치(LCP 2.5초 미만, INP 200 밀리초 미만)를 달성하면 사용자 이탈률을 낮추고 유기적 검색(SEO) 성과를 직접적으로 높일 수 있습니다 [1-3].
## 📖 Core Content
- **[[Largest Contentful Paint (LCP)|Largest Contentful Paint (LCP]] 최적화**
LCP는 브라우저 화면의 가장 큰 콘텐츠 요소가 렌더링되는 시간을 측정하며, 이를 2.5초 미만으로 유지하는 것이 목표입니다 [1].
- **코드 스플리팅(Code Splitting):** 기본적으로 번들러는 전체 애플리케이션을 하나의 큰 파일로 묶지만, `React.lazy()` 등을 통해 라우트 수준에서 코드를 분할하면 초기 번들 크기를 30~50%가량 줄여 LCP를 크게 개선할 수 있습니다 [4].
- **렌더링 전략 변경:** 클라이언트 측 렌더링(CSR)은 초기 로딩이 느리다는 단점이 있습니다 [5, 6]. 따라서 서버 사이드 렌더링(SSR)이나 정적 사이트 생성(SSG)을 도입해 자바스크립트 파싱 전에 완성된 HTML을 사용자에게 즉시 제공함으로써 LCP 병목 현상을 해소할 수 있습니다 [7-9].
- **이미지 최적화:** WebP나 AVIF 같은 현대적인 이미지 포맷을 사용하여 파일 크기를 줄이고, 화면에 보일 때만 이미지를 로드하는 `loading="lazy"` 지연 로딩을 도입해 초기 주요 리소스와의 대역폭 경쟁을 막습니다 [10, 11].
- **[[Interaction to Next Paint (INP)|Interaction to Next Paint (INP]] 최적화**
INP는 기존의 First Input Delay(FID)를 대체한 지표로, 클릭이나 키보드 입력 같은 상호작용 지연 시간을 200ms 이내로 응답하게 만드는 것이 핵심입니다 [2].
- **동시성 렌더링([[Concurrent Rendering|Concurrent Rendering]]):** React 19의 `useTransition``[[useDeferredValue|useDeferredValue]]` 훅을 통해 무거운 상태 업데이트(예: 대규모 목록 필터링)를 후순위로 미루고, 긴급한 사용자 입력(타이핑 등)을 먼저 처리하여 메인 스레드의 응답성을 유지합니다 [2, 12, 13].
- **메모이제이션과 연산 최적화:** 부모 컴포넌트의 상태가 변할 때 발생하는 불필요한 '리렌더링 폭포(Re-render Cascade)' 현상을 막기 위해 `React.memo`, `useMemo`, `useCallback`을 활용합니다 [14-16]. 더불어 키 입력마다 발생하는 과도한 API 호출을 줄이기 위해 디바운싱(Debouncing)을 적용합니다 [17].
- **목록 가상화(Virtualization):** 수백, 수천 개의 항목이 포함된 긴 목록을 렌더링할 때, 화면에 보이는 노드만 렌더링하는 가상화를 도입하면 레이아웃 및 페인트 작업 부하를 방지하여 상호작용 속도를 높입니다 [2, 18, 19].
- **[[React Server Components (RSC)|React Server Components (RSC]]:** 읽기 전용 데이터 컴포넌트를 서버에서 전적으로 실행함으로써 클라이언트의 자바스크립트 크기를 40~60% 감소시키고, 상호작용 시 브라우저 메인 스레드가 처리할 코드를 줄여 INP를 직접적으로 낮출 수 있습니다 [20].
- **Cumulative Layout [[Shift|Shift]] (CLS) 관리 및 성능 프로파일링**
- 시각적 안정성을 측정하는 CLS는 0.1 미만을 목표로 하며, 불필요한 DOM 노드를 줄이기 위한 React Fragment의 사용, 이미지의 명시적 크기 지정 등의 방법으로 개선합니다 [2, 21].
- 최적화를 적용하기 전에 항상 `React DevTools Profiler``[[Lighthouse|Lighthouse]]`를 사용하여 병목을 유발하는 컴포넌트를 찾고, 프로덕션 환경의 실측 데이터를 얻기 위해 `Web Vitals` 라이브러리로 필드 데이터를 모니터링해야 합니다 [22-26].
## 🔗 Knowledge Connections
- **Related Topics:** [[Largest Contentful Paint (LCP)|Largest Contentful Paint (LCP]], Interaction to Next Paint (INP), Concurrent Rendering, [[Server-Side Rendering (SSR)|Server-Side Rendering (SSR]], [[React Server Components (RSC)|React Server Components (RSC]]
- **Projects/Contexts:** [[React Performance Optimization|React Performance Optimization]], Search Engine Optimization (SEO) [[Strategy|Strategy]]
- **Contradictions/Notes:** Lighthouse와 같은 도구로 측정한 연구실 데이터(Lab measurements)는 다양한 기기 성능과 네트워크 조건을 겪는 실제 사용자들의 경험(Field data)과 항상 일치하지는 않으므로 프로덕션 상의 Web Vitals 데이터를 함께 수집해야 합니다 [23, 24].
---
*Last updated: 2026-04-25*
@@ -1,18 +0,0 @@
# [[Core Web Vitals|Core Web Vitals]]
## 📌 Brief Summary
Core Web Vitals(코어 웹 바이탈)은 웹사이트의 실제 성능과 사용자 경험을 평가하는 필수 지표로, 로딩 속도, 레이아웃의 안정성, 사용자 입력에 대한 반응 속도를 측정합니다 [1]. 핵심 지표로는 LCP(Largest Contentful Paint), CLS(Cumulative Layout [[Shift|Shift]]), INP(Interaction to Next Paint)가 있으며, 이는 구글의 검색 순위(Ranking signal)와 모바일 우선 인덱싱에 직접적인 영향을 미칩니다 [2, 3].
## 📖 Core Content
* **핵심 지표와 목표치**: Core Web Vitals는 크게 세 가지 주요 지표로 구성됩니다. LCP(Largest Contentful Paint)는 주요 콘텐츠의 로딩 속도를 의미하며 2.5초 미만을 유지해야 하고, CLS(Cumulative Layout Shift)는 레이아웃의 시각적 안정성을 나타내며 0.1 미만이어야 하며, INP(Interaction to Next Paint)는 사용자의 입력에 대한 반응성을 측정하여 200밀리초 미만을 목표로 최적화해야 합니다 [4].
* **CSS 및 반응형 디자인과의 연관성**: 잘못된 이미지 크기 지정, 너비(width) 및 높이(height) 속성 누락, 최적화되지 않은 폰트 등은 모바일 환경에서 Core Web Vitals 점수 하락의 가장 흔한 원인이 됩니다 [2, 3]. 잘 구축된 반응형 레이아웃은 불필요한 레이아웃 이동(Layout shift)을 줄이고 로딩 시간을 개선하며 사용자 상호작용을 민첩하게 만듭니다 [1].
* **성능 최적화 기법**: CLS를 방지하기 위해 컨테이너에 `aspect-ratio` 속성을 적용하거나 명시적인 너비와 높이를 지정해야 합니다 [5, 6]. LCP 향상을 위해서는 LCP 요소(주로 히어로 이미지)에 `fetchpriority="high"`를 설정하고 폴드(fold) 아래의 이미지는 지연 로딩(lazy-load) 처리하며, WebP나 AVIF 같은 압축률이 높은 차세대 포맷을 사용하는 방법이 있습니다 [5-7].
* **SEO 및 비즈니스 영향**: 구글은 페이지 경험 신호의 일부로 Core Web Vitals를 활용하므로, 로딩이 느리고 레이아웃 이동이 잦은 비반응형 웹사이트는 검색 결과에서 성능이 저하될 수 있습니다 [3, 4]. 따라서 이 지표들을 지속적으로 모니터링하고 최적화하는 것은 2026년 현재 반응형 웹 디자인의 핵심 요구 사항입니다 [4, 8].
## 🔗 Knowledge Connections
- **Related Topics:** [[Responsive Web Design|Responsive Web Design]], [[CSS Performance Optimization|CSS Performance Optimization]]
- **Projects/Contexts:** [[Search Engine Optimization (SEO)|Search Engine Optimization (SEO]]
- **Contradictions/Notes:** 소스 전반에 걸쳐 CSS 및 반응형 디자인의 최적화가 Core Web Vitals 지표 개선으로 직결된다고 강조하고 있으며, 소스 간 상충되는 의견은 존재하지 않습니다.
---
*Last updated: 2026-04-26*
@@ -1,20 +0,0 @@
# [[Critical Rendering Path (CRP)|Critical Rendering Path (CRP]]
## 📌 Brief Summary
[[Critical Rendering Path|Critical Rendering Path]] (CRP)는 웹 브라우저가 HTML, CSS, JavaScript 코드를 수신하여 화면의 픽셀로 변환하기 위해 실행하는 일련의 단계입니다 [1, 2]. 이 경로는 DOM(문서 객체 모델) 및 [[CSSOM|CSSOM]](CSS 객체 모델) 구축, 렌더 트리 생성, 레이아웃 계산, 화면 페인팅 등의 핵심 과정으로 구성됩니다 [2]. CRP를 최적화하면 최초 렌더링(Time to First Render) 시간을 단축하고, 초당 60프레임의 원활한 상호작용을 보장하며, 성능 저하나 끊김(Jank)을 방지할 수 있습니다 [2, 3].
## 📖 Core Content
- **[[DOM (Document Object Model)|DOM(Document Object Model]] 구축:** 브라우저는 HTML 데이터를 수신하면 점진적 파싱(incremental parsing)을 시작합니다 [3, 4]. 수신된 바이트를 문자, 토큰, 노드로 변환한 뒤 계층적인 DOM 트리를 구축합니다 [3, 4].
- **[[CSSOM(CSS Object Model)|CSSOM(CSS Object Model]] 구축:** CSS는 HTML과 달리 점진적으로 처리되지 않으며 렌더링 차단(render-[[Blocking|Blocking]]) 리소스로 작동합니다 [5, 6]. 브라우저는 화면에 스타일이 지정되지 않은 콘텐츠가 깜빡이는 현상(FOUC)을 막기 위해 렌더 트리를 만들기 전 모든 연결된 스타일시트를 다운로드하고 구문 분석하여 CSSOM을 완성해야 합니다 [5, 6].
- **렌더 트리([[Render Tree|Render Tree]]) 생성:** DOM과 CSSOM 트리가 준비되면 이를 결합하여 렌더 트리를 합성합니다 [7, 8]. 이 트리에는 화면 렌더링에 필요한 가시적 노드만 포함되며, `<script>`, `<meta>` 요소나 `display: none` 처리된 요소 등 시각적 레이아웃에 영향을 주지 않는 노드는 제외됩니다 [7-9].
- **레이아웃(Layout / Reflow):** 렌더 트리가 구축되면 브라우저는 뷰포트 크기와 박스 모델을 기반으로 각 요소의 정확한 화면 상 위치(x, y)와 치수(너비, 높이)를 계산합니다 [10-12].
- **페인트(Paint / Repaint) 및 합성(Compositing):** 페인트 단계에서는 계산된 기하학적 구조와 스타일(색상, 그림자, 텍스트 등)을 바탕으로 요소를 실제 픽셀로 화면에 그립니다 [13-15]. 마지막으로 합성 단계에서는 여러 레이어를 하나의 최종 이미지로 결합하며, 최신 브라우저에서는 성능을 위해 이 과정을 GPU에 오프로드하여 처리합니다 [13, 16].
- **성능 최적화 전략:** CRP 최적화를 위해서는 다운로드해야 하는 렌더링 차단 리소스(`<head>` 내부의 CSS 및 동기식 JavaScript)의 크기와 개수를 최소화해야 합니다 [17-19]. 중요하지 않은 리소스의 로드를 지연시키거나 비동기로 처리하여 브라우저의 렌더링 파이프라인이 멈추지 않도록 구성하는 것이 핵심입니다 [17, 20].
## 🔗 Knowledge Connections
- **Related Topics:** [[DOM (Document Object Model)|DOM (Document Object Model]], CSSOM (CSS Object Model), [[Render Tree|Render Tree]], Reflow, Repaint
- **Projects/Contexts:** 최신 프론트엔드 개발의 기초 구조 설계, 코어 웹 바이탈([[Core Web Vitals|Core Web Vitals]]) 성능 개선, React의 [[Virtual DOM|Virtual DOM]] 도입을 통한 렌더링 병목 현상 해결 컨텍스트 [1, 2, 21].
- **Contradictions/Notes:** CSS 선택자의 구체성(specificity)을 높게 작성할 경우 파싱 비용이 증가하지만, 현대 브라우저 엔진은 구문 분석 속도가 매우 빠르기 때문에 이러한 선택자 최적화가 CRP 전체 성능에 미치는 영향은 마이크로초(microseconds) 수준에 불과하여 최적화의 주된 우선순위로 삼기에는 실효성이 부족할 수 있습니다 [22].
---
*Last updated: 2026-04-25*
@@ -1,20 +0,0 @@
# [[Critical Rendering Path|Critical Rendering Path]]
## 📌 Brief Summary
[[Critical Rendering Path (CRP)|Critical Rendering Path (CRP]]는 브라우저가 HTML, CSS, JavaScript를 수신하여 화면의 픽셀로 변환하기 위해 거치는 일련의 단계적 과정을 의미합니다[1]. 이 과정은 DOM 트리 및 CSSOM 트리 구축, [[Render Tree|Render Tree]] 합성, Layout(Reflow), 그리고 Paint(Repaint) 및 Compositing 단계로 진행됩니다[1, 2]. CRP를 이해하고 최적화하는 것은 렌더링 차단 요소를 줄이고 불필요한 Reflow 및 Repaint를 최소화하여 빠른 초기 렌더링과 매끄러운 사용자 상호작용을 보장하는 프론트엔드 성능 엔지니어링의 핵심입니다[3, 4].
## 📖 Core Content
* **[[DOM (Document Object Model)|DOM (Document Object Model]] 구축:** 브라우저는 서버로부터 HTML 데이터를 점진적으로 파싱하여 DOM 트리를 구축합니다[2, 5]. 수신된 바이트는 토큰 및 노드로 변환되어 계층 구조를 형성하며, 노드의 수가 많을수록 이후 렌더링 경로의 연산 시간이 길어집니다[2, 5, 6].
* **CSSOM (CSS Object Model) 구축:** DOM과 달리 CSSOM 구축은 점진적으로 이루어지지 않으며, 파싱이 완료될 때까지 렌더링을 차단(Render-[[Blocking|Blocking]])합니다[6-8]. 이는 스타일이 뒤늦게 덮어씌워지면서 스타일이 적용되지 않은 콘텐츠가 화면에 번쩍이는 현상(FOUC)을 방지하기 위함입니다[6, 7].
* **Render Tree 합성:** DOM과 CSSOM이 완성되면, 브라우저는 이 둘을 결합해 화면에 실제로 그려지는 가시적 노드(Visible nodes)만 포함하는 Render Tree를 만듭니다[9-11]. `<script>`, `<meta>` 요소나 `display: none` 스타일이 적용된 노드는 렌더 트리에서 완전히 제외되지만, 레이아웃 공간을 차지하는 `visibility: hidden` 요소는 포함됩니다[9-12].
* **Layout (Reflow):** Render Tree를 기반으로 뷰포트 크기와 박스 모델에 맞춰 각 요소의 정확한 기하학적 위치와 크기를 계산하는 단계입니다[13-15]. 창 크기가 변하거나, DOM 요소의 추가/제거, 혹은 너비나 여백 등 레이아웃에 영향을 주는 속성이 변경될 경우 Reflow가 발생하며 이는 매우 큰 연산 비용을 수반합니다[16-19].
* **Paint (Repaint) 및 Compositing:** Layout 계산이 끝나면 각 요소를 픽셀로 화면에 그리는 Paint(또는 Rasterizing) 과정이 진행됩니다[20-23]. 레이아웃 변화 없이 배경색 등 시각적 속성만 변할 때는 Repaint만 촉발됩니다[18, 20, 24]. 이후 서로 다른 레이어들을 하나의 화면으로 합치는 Compositing 단계를 거치며, 특정 효과(예: transform)는 GPU로 오프로드하여 성능을 최적화할 수 있습니다[20, 25].
* **React 도입과의 연관성:** 전통적으로 브라우저의 DOM을 직접 조작하는 것은 필연적으로 비용이 큰 Reflow와 Repaint 과정을 연쇄적으로 유발하여 속도 저하를 일으킵니다[26]. React는 이 한계를 극복하기 위해 메모리에 경량화된 [[Virtual DOM|Virtual DOM]]을 구축하고, 상태 변경 시 휴리스틱 Diffing 알고리즘([[Reconciliation|Reconciliation]])을 통해 변경된 최소한의 노드만 실제 DOM에 반영하여 렌더링 경로의 비효율을 크게 줄입니다[3, 26, 27].
## 🔗 Knowledge Connections
- **Related Topics:** [[브라우저 렌더링 과정 (HTML → CSSOM → Render Tree)|브라우저 렌더링 과정 (HTML → CSSOM → Render Tree]], Reflow / Repaint 최소화 방법, [[DOM vs Virtual DOM|DOM vs Virtual DOM]]
- **Projects/Contexts:** [[렌더링 최적화 개념 설명 자료|렌더링 최적화 개념 설명 자료]], [[“React가 빠른 이유”|“React가 빠른 이유”]]
- **Contradictions/Notes:** CSS 선택자(Selector)의 복잡도는 파싱 속도에 영향을 주지만, 최신 브라우저 엔진은 매우 빠르기 때문에 선택자 구체성을 최적화해서 얻는 성능적 이득은 마이크로초 단위에 불과합니다. 따라서 실질적인 최적화를 위해서는 선택자 구조 개선보다는 불필요한 렌더링 차단 리소스 크기를 줄이거나 로딩 순서를 제어하는 것이 성능 개선(CRP 최적화)에 훨씬 효과적입니다[28, 29].
---
*Last updated: 2026-04-25*
@@ -1,25 +0,0 @@
# [[DOM (Document Object Model)|DOM (Document Object Model]]
## 📌 Brief Summary
[[DOM (Document Object Model)|DOM(Document Object Model]]은 브라우저가 수신한 HTML 문서 데이터를 파싱하여 생성하는 페이지 구조의 계층적 트리 표현입니다 [1-3]. 브라우저는 HTML 태그의 포함 관계를 바탕으로 부모 및 자식 노드의 트리를 형성하며, `<html>` 요소를 루트 노드로 갖습니다 [4, 5]. DOM은 페이지의 모든 콘텐츠 정보를 담고 있으며, 스타일 정보를 담은 CSSOM과 결합해 최종 화면 출력에 필요한 렌더 트리([[Render Tree|Render Tree]])를 형성하는 브라우저 렌더링 과정의 핵심 기반입니다 [6-8].
## 📖 Core Content
* **DOM 트리의 점진적 구축 (Incremental Construction)**
브라우저는 네트워크를 통해 HTML 문서의 전체 데이터를 다 받기 전부터 점진적으로 DOM 트리를 구축할 수 있습니다 [1, 4]. 초기 14KB의 데이터 패킷이 수신되면 바이트를 문자로, 문자를 토큰(startTag 및 endTag 등)으로 변환한 뒤, 최종적으로 노드(Node)로 변환하여 트리를 조립합니다 [1, 4]. 이 점진적 생성 메커니즘 덕분에 네트워크 요청이 진행 중인 상태에서도 브라우저는 렌더링 준비를 시작할 수 있습니다 [9].
* **렌더링 파이프라인에서의 DOM과 CSSOM**
DOM은 문서의 '콘텐츠'를 표현하는 반면, CSSOM은 해당 콘텐츠의 '스타일'을 정의하는 독립적인 트리 구조입니다 [9, 10]. 이 두 모델은 브라우저에 의해 결합되어 화면에 시각적으로 출력되어야 하는 노드만을 포함하는 '렌더 트리(Render Tree)'로 합성됩니다 [6, 11, 12]. 이 과정에서 `<script>`, `<meta>` 또는 `display: none`이 적용된 요소처럼 시각적 영향을 주지 않는 DOM 노드는 렌더 트리에서 제외됩니다 [8, 11-13].
* **크기와 복잡성이 성능에 미치는 영향**
DOM 트리의 깊이와 생성된 노드의 개수는 웹 성능과 직결됩니다 [5, 9]. 노드의 수가 많아질수록 렌더 트리 합성, 레이아웃(Reflow), 페인트 단계에서 브라우저가 처리해야 할 계산의 양과 시간이 증가하여 애플리케이션의 성능이 저하될 수 있습니다 [5, 7, 9, 14]. 불필요한 래퍼를 줄이고 React Fragment 등을 사용하여 DOM 노드 수를 최소화하는 것이 성능 향상에 도움이 됩니다 [15].
* **DOM 조작의 비효율성과 최적화**
[[JavaScript|JavaScript]]를 사용해 DOM을 직접 조작하고 크기나 위치 등을 변경하면, 브라우저는 문서 전체의 레이아웃(Reflow)과 페인트(Repaint) 과정을 다시 실행해야 하므로 처리 비용이 매우 높습니다 [16-18]. 이를 최적화하기 위해서는 사용된 DOM 노드나 속성값을 캐싱하고, DOM의 읽기 및 쓰기 작업을 분리하여 레이아웃 스래싱(Layout Thrashing)을 방지해야 합니다 [16, 19, 20]. React와 같은 프레임워크는 실제 DOM을 직접 수정하는 비효율성을 피하고자 메모리 내에 가벼운 사본인 가상 DOM([[Virtual DOM|Virtual DOM]])을 생성하여 조작을 추상화합니다 [17, 21, 22].
## 🔗 Knowledge Connections
- **Related Topics:** CSSOM (CSS Object Model), [[Render Tree|Render Tree]], Virtual DOM, [[Critical Rendering Path (CRP)|Critical Rendering Path (CRP]], Reflow (Layout), Repaint
- **Projects/Contexts:** 프론트엔드 성능 최적화(DOM 접근 최소화 및 렌더링 파이프라인 관리), React의 렌더링 엔진 구조 및 재조정([[Reconciliation|Reconciliation]]) 과정 이해 [6, 17, 23, 24].
- **Contradictions/Notes:** DOM 구축은 HTML을 파싱하면서 '점진적(incremental)'으로 이루어지지만, CSSOM 구축은 렌더링을 차단(render-[[Blocking|Blocking]])하며 점진적으로 처리되지 않는다는 구조적 차이가 있습니다 [1, 7, 9].
---
*Last updated: 2026-04-25*
@@ -1,36 +0,0 @@
# [[DOM vs Virtual DOM|DOM vs Virtual DOM]]
## 📌 Brief Summary
DOM(문서 객체 모델)은 브라우저가 HTML을 파싱하여 생성하는 트리 구조로, 직접적인 DOM 조작은 렌더링 경로(레이아웃 및 페인트)를 매번 트리거하여 성능 저하를 유발합니다 [1, 2]. 반면 [[Virtual DOM|Virtual DOM]](가상 DOM)은 React가 수동적인 DOM 조작의 비효율성을 해결하기 위해 도입한 개념으로, UI의 이상적인 상태를 메모리에 가벼운 JavaScript 객체 형태로 저장하는 방식입니다 [2-4]. React는 새로운 Virtual DOM과 이전 버전을 비교(Diffing)하여 실제 변경된 부분만 실제 DOM에 반영([[Reconciliation|Reconciliation]])함으로써 브라우저의 리플로우와 리페인트를 최소화하고 렌더링 성능을 최적화합니다 [3-5].
## 📖 Core Content
* **[[DOM (Document Object Model)|DOM(Document Object Model]]의 특성과 한계**
* 브라우저는 수신된 HTML 바이트를 문자, 토큰, 노드로 변환하여 점진적으로 DOM 트리를 구축합니다 [1].
* DOM은 페이지의 구조와 콘텐츠를 나타내며, 노드 수가 많고 트리의 깊이가 깊을수록 브라우저의 레이아웃(Reflow) 및 페인트(Repaint) 등 중요 렌더링 경로([[Critical Rendering Path|Critical Rendering Path]]) 작업에 걸리는 연산 부담이 증가합니다 [6, 7].
* 웹 애플리케이션에서 DOM을 직접 수정하는 작업은 본질적으로 느립니다 [2]. DOM의 변경은 레이아웃과 페인트 단계를 트리거하며, 여러 노드를 개별적으로 업데이트할 경우 중복된 재계산을 유발하기 때문입니다 [2].
* **Virtual DOM의 개념 및 도입 목적**
* 수동적인 DOM 조작이 가진 비효율성을 추상화하기 위해 React에서 도입한 아키텍처가 Virtual DOM입니다 [2].
* 이는 UI를 메모리 내에 가벼운 JavaScript 객체 형태로 유지하는 표현 방식입니다 [2, 3].
* 개발자가 UI의 이상적인 상태를 선언적으로 정의하면, React(ReactDOM 등)가 실제 DOM을 해당 상태와 일치하도록 알아서 동기화하므로, 개발자는 속성 조작이나 이벤트 처리, 수동적인 DOM 업데이트 등을 직접 처리할 필요가 없습니다 [4].
* Virtual DOM 트리는 설계상 불변(immutable) 객체로 취급됩니다 [8].
* **재조정(Reconciliation)과 Diffing 알고리즘**
* 상태나 속성(props)이 업데이트되면 React는 새로운 Virtual DOM 트리를 생성하고, 이를 이전 버전의 트리와 비교(Diffing)하여 실제 DOM을 가장 효율적으로 업데이트할 방법을 결정합니다 [2, 3, 9]. 이 동기화 과정을 재조정(Reconciliation)이라고 합니다 [3, 4].
* 두 트리를 비교하는 일반적인 알고리즘은 $O(n^3)$의 복잡도를 가져, 요소가 많아질 경우 실시간 연산에 부적합할 만큼 비용이 큽니다 [9-11].
* 대신 React는 두 가지 가정을 기반으로 $O(n)$ 복잡도의 휴리스틱 Diffing 알고리즘을 사용합니다 [10, 11].
1. 서로 다른 타입의 요소는 전혀 다른 트리를 생성한다고 가정하여 기존 트리를 허물고 완전히 새로 구축합니다 [10-12].
2. 개발자가 제공하는 `key` 속성을 통해 여러 렌더링에 걸쳐 안정적으로 유지되는 자식 요소가 무엇인지 식별합니다 [10, 11].
* 이러한 접근 방식을 통해 React는 변경된 특정 속성이나 노드만을 수정하고, 기본 DOM 노드와 상태를 가능한 한 보존하여 효율성을 높입니다 [13-15].
* **성능 최적화 관점 (React가 빠른 이유)**
* Virtual DOM은 일시적인 프레젠테이션 상태를 지속적인 애플리케이션 상태와 분리하고 변경되지 않은 프레젠테이션 상태를 보존함으로써, 브라우저의 무거운 DOM 연산을 줄이고 UI 렌더링 성능을 개선합니다 [3].
* 그러나 Virtual DOM의 Diffing 작업 자체가 연산 비용이 전혀 없는 것은 아닙니다 [16]. Virtual DOM은 실제 DOM이 업데이트될 필요가 없는 경우는 잘 잡아내지만, 부모 컴포넌트의 상태 변경으로 인해 하위 컴포넌트 전체가 재렌더링되는 폭포수 현상(Re-Render Cascade)이 발생하면 불필요한 Diffing 연산이 낭비될 수 있습니다 [16, 17]. 이를 최소화하려면 `React.memo` 등을 통해 선택적으로 리렌더링을 차단하는 최적화가 병행되어야 합니다 [16].
## 🔗 Knowledge Connections
- **Related Topics:** [[Critical Rendering Path|Critical Rendering Path]], Reflow and Repaint, Reconciliation, [[React Fiber Architecture|React Fiber Architecture]]
- **Projects/Contexts:** [[프론트엔드 기초 구조 이해|프론트엔드 기초 구조 이해]], 브라우저 렌더링 과정 (HTML → CSSOM → [[Render Tree|Render Tree]], [[“React가 빠른 이유” 및 렌더링 최적화 개념|“React가 빠른 이유” 및 렌더링 최적화 개념]]
- **Contradictions/Notes:** Virtual DOM이 수동 DOM 조작 비용을 크게 줄여주어 React의 빠른 성능을 보장하지만, 소스에 따르면 "Virtual DOM의 Diffing 작업 자체가 무료는 아니며(not free), 무분별한 리렌더링 폭포수(Re-Render Cascade)가 발생할 경우 연산 낭비와 성능 저하의 주원인이 될 수 있다"고 경고합니다 [16]. 따라서 완벽한 성능을 위해서는 Virtual DOM에만 의존하지 않고 메모이제이션(Memoization)을 통한 컴포넌트 최적화가 필요합니다 [16].
---
*Last updated: 2026-04-25*
@@ -1,31 +0,0 @@
# [[DOM 및 CSSOM|DOM 및 CSSOM]]
## 📌 Brief Summary
DOM(문서 객체 모델)과 [[CSSOM|CSSOM]](CSS 객체 모델)은 브라우저의 핵심 렌더링 경로(Critical Rendering Path)에서 웹 페이지를 화면에 그리기 위해 생성되는 두 가지 독립적인 트리 구조 데이터입니다 [1, 2]. DOM은 HTML 마크업을 점진적으로 파싱하여 문서의 구조와 내용을 나타냅니다 [3, 4]. 반면, CSSOM은 문서에 적용될 스타일 규칙을 정의하며, 렌더링 시 스타일이 적용되지 않은 콘텐츠가 깜빡이는 현상(FOUC)을 방지하기 위해 렌더링 차단(render-Blocking) 방식으로 생성됩니다 [5, 6]. 이 두 트리가 결합하여 화면에 표시될 시각적 요소들만 포함하는 렌더 트리([[Render Tree|Render Tree]])를 최종적으로 형성합니다 [7, 8].
## 📖 Core Content
**[[DOM (Document Object Model)|DOM(Document Object Model]] 구축**
- 브라우저는 HTML 응답을 받으면 데이터를 문자, 토큰(token)으로 변환하고, 이를 다시 노드(node)로 변환하여 계층적인 DOM 트리를 구축합니다 [3, 4, 9].
- DOM 트리는 문서의 콘텐츠와 각 요소 간의 관계 및 계층 구조를 나타냅니다 [4, 8, 9].
- DOM 구축은 점진적(incremental)으로 이루어지므로, 브라우저는 네트워크 요청이 진행 중인 상태에서도 파싱을 시작하여 트리를 구성할 수 있습니다 [3, 5, 6].
- 단, DOM 노드의 수가 많아질수록 레이아웃 및 페인트 등 이후의 렌더링 단계에서 브라우저의 연산 부담이 커지고 처리 시간이 길어집니다 [5, 6, 9].
**[[CSSOM(CSS Object Model)|CSSOM(CSS Object Model]] 구축**
- CSSOM은 DOM이 어떻게 스타일링될지에 대한 모든 정보를 담고 있으며, 브라우저가 CSS 규칙을 이해하고 적용할 수 있도록 만든 트리 구조의 스타일 맵입니다 [2, 6, 8].
- DOM과 달리 CSSOM 구축은 점진적이지 않으며, 문서의 렌더링을 차단(render-blocking)합니다 [5, 6].
- 브라우저는 스타일이 적용되지 않은 원시 HTML이 사용자에게 노출되는 현상(FOUC)을 막기 위해 링크된 모든 스타일시트를 다운로드하고 파싱할 때까지 렌더링을 중단합니다 [5].
- CSS 규칙은 하향식으로 종속(Cascade)되는 특성이 있어 파싱 도중 이전 규칙이 덮어써질 수 있으므로, 완전히 파싱이 끝나기 전까지는 렌더 트리를 구축하는 데 사용될 수 없습니다 [10, 11].
- 브라우저는 CSS 선택자를 오른쪽에서 왼쪽으로 파싱합니다 [12]. 따라서 `.container.navigation.item`과 같이 구체적인 선택자는 단순히 `.item`을 찾는 것보다 DOM 트리를 거슬러 올라가며 조상 관계를 확인해야 하므로 연산 비용이 더 듭니다 [12, 13].
**렌더 트리(Render Tree) 합성**
- DOM과 CSSOM 구조가 모두 준비되면, 브라우저는 이 둘을 결합하여 화면에 그릴 렌더 트리를 생성합니다 [7, 14].
- 렌더 트리는 시각적으로 렌더링되는 요소들만 캡처합니다 [7]. 따라서 시각적 레이아웃에 영향을 주지 않는 `<script>`, `<meta>` 요소나, CSS에 의해 `display: none`으로 처리된 요소는 렌더 트리에서 제외됩니다 [7, 8, 14, 15].
- 하지만 `visibility: hidden`이 적용된 요소는 보이지 않더라도 레이아웃 상에서 공간을 차지하므로 렌더 트리에 포함됩니다 [15].
## 🔗 Knowledge Connections
- **Related Topics:** `[[Critical Rendering Path|Critical Rendering Path]]`, `Render Tree`, `[[Reflow and Repaint|Reflow and Repaint]]`
- **Projects/Contexts:** `[[프론트엔드 성능 최적화|프론트엔드 성능 최적화]]`, `브라우저 렌더링 파이프라인 이해`
- **Contradictions/Notes:** CSS 선택자의 구체성이 CSSOM 생성 연산 속도에 영향을 미치지만, 최신 브라우저는 파싱 속도가 매우 빨라 이로 인한 지연은 마이크로초 단위에 불과합니다 [11, 13]. 따라서 과도하게 선택자 구체성 최적화에 집착하기보다는 미니파이(minification)나 렌더링 차단을 방지하는 다른 CSS 최적화 기법에 집중하는 것이 좋습니다 [13].
---
*Last updated: 2026-04-25*
@@ -1,25 +0,0 @@
# [[DOM (Document Object Model)|DOM(Document Object Model]]
## 📌 Brief Summary
DOM(Document Object Model)은 브라우저가 HTML 마크업을 내부적으로 표현하기 위해 생성하는 계층적인 트리 구조의 객체 모델입니다 [1, 2]. 브라우저가 HTML 데이터를 수신하면서 점진적으로 생성하며, 웹 페이지의 모든 콘텐츠와 요소 간의 구조적 관계를 담고 있습니다 [1, 3, 4]. 자바스크립트([[JavaScript|JavaScript]]) 내의 다양한 API를 통해 DOM에 접근하고 이를 동적으로 조작할 수 있습니다 [2].
## 📖 Core Content
- **DOM 생성 과정 (DOM Construction Process)**
브라우저는 서버로부터 HTML 문서를 수신하면 즉시 파싱(Parsing)을 시작합니다 [5]. 이 과정은 전체 문서가 도착하기를 기다리지 않고 점진적(incremental)으로 이루어집니다 [1]. 수신된 데이터(바이트)는 문자로 변환되고, 이후 토큰(tokens)으로 변환된 다음 최종적으로 노드(nodes)로 변환되어 계층적인 DOM 트리를 형성합니다 [1, 6]. 시작 태그(startTag)와 종료 태그(endTag) 사이에 다른 태그들이 포함되는 방식으로 노드 간의 계층 구조가 정의됩니다 [6].
- **트리 구조와 구성 (Tree Structure and Composition)**
DOM 트리는 문서의 콘텐츠를 묘사하며, `<html>` 요소가 트리 구조의 첫 번째 요소이자 루트(root) 노드가 됩니다 [4]. 다른 요소 안에 중첩된 요소들은 자식 노드(child nodes)가 되어 트리 내부에서 각 요소의 관계와 계층을 반영합니다 [4]. 생성된 DOM 트리는 이후 스타일 정보를 담고 있는 [[CSSOM(CSS Object Model)|CSSOM(CSS Object Model]]과 결합하여 화면에 그려질 요소를 결정하는 렌더 트리([[Render Tree|Render Tree]])를 구축하는 데 사용됩니다 [7, 8].
- **성능에 미치는 영향 (Performance Implications)**
DOM 트리의 깊이와 복잡성은 브라우저의 성능과 직결됩니다 [9]. DOM에 존재하는 노드의 수가 많아질수록 렌더 트리 생성, 레이아웃(Layout), 페인트(Paint)와 같은 중요 렌더링 경로([[Critical Rendering Path|Critical Rendering Path]])의 후속 작업에 소요되는 시간과 연산 부담이 커지게 됩니다 [3, 4, 9].
- **직접적인 DOM 조작의 한계 (Limitations of Direct DOM Manipulation)**
자바스크립트 등을 통해 DOM을 직접 변경하는 작업은 브라우저의 레이아웃(Reflow)과 페인트 단계를 지속적으로 트리거하기 때문에 본질적으로 속도가 느리고 비용이 많이 듭니다 [10]. 애플리케이션이 복잡해질 경우 여러 노드를 개별적으로 업데이트하면 중복 연산이 발생하며, 이는 React와 같은 프레임워크가 가상 DOM([[Virtual DOM|Virtual DOM]])을 도입하게 된 핵심 배경이 되었습니다 [10].
## 🔗 Knowledge Connections
- **Related Topics:** [[CSSOM(CSS Object Model)|CSSOM(CSS Object Model]], Critical Rendering Path(CRP), Render Tree, [[Virtual DOM|Virtual DOM]], Reflow / Repaint
- **Projects/Contexts:** 브라우저 렌더링 과정 ([[Browser|Browser]] Rendering Process), 프론트엔드 성능 최적화 및 React의 Virtual DOM 도입 배경 이해 [7, 10, 11]
- **Contradictions/Notes:** 소스 간의 모순된 정보는 없습니다. 참고로 DOM의 생성은 점진적(incremental)으로 진행되어 문서를 파싱하는 동안에도 화면을 그리기 시작할 수 있지만, [[CSSOM|CSSOM]]의 생성은 렌더링을 차단(render-[[Blocking|Blocking]])한다는 점에서 두 모델의 구축 방식에 차이가 있습니다 [3, 9].
---
*Last updated: 2026-04-25*
-19
View File
@@ -1,19 +0,0 @@
# [[DOM|DOM]]
## 📌 Brief Summary
[[DOM (Document Object Model)|DOM(Document Object Model]]은 브라우저가 수신한 HTML 문서를 구문 분석하여 구성하는 문서의 구조와 콘텐츠를 나타내는 계층적 트리 구조입니다 [1-3]. 이는 브라우저의 렌더링 과정인 크리티컬 렌더링 패스(CRP)에서 CSSOM과 결합하여 화면에 그려질 렌더 트리(Render Tree)를 생성하는 핵심 기초가 됩니다 [4-6]. [[JavaScript|JavaScript]]를 통한 직접적인 DOM 조작은 레이아웃(Reflow)과 페인트 작업을 유발해 성능을 저하시키므로, 최신 프레임워크인 React는 이를 최적화하기 위해 [[Virtual DOM|Virtual DOM]]을 활용합니다 [7].
## 📖 Core Content
* **DOM 트리의 점진적 구축:** 브라우저는 HTML 응답을 받으면 바이트(bytes)를 문자, 토큰(token), 노드(node)로 변환하는 과정을 거쳐 DOM 트리를 구성합니다 [3, 8, 9]. HTML의 시작 태그와 종료 태그는 노드 간의 부모, 자식, 형제 관계와 같은 계층 구조를 정의하며, `<html>` 요소가 문서 트리의 루트 노드가 됩니다 [3, 9]. DOM의 구축은 점진적(incremental)으로 이루어지기 때문에, 브라우저는 데이터를 수신하는 도중에도 트리를 구축할 수 있습니다 [8, 9].
* **렌더 트리(Render Tree)의 형성:** DOM은 페이지의 '콘텐츠'를 담고 있으며, 페이지의 '스타일'을 담고 있는 [[CSSOM(CSS Object Model)|CSSOM(CSS Object Model]]과 결합하여 렌더 트리를 완성합니다 [5, 6, 10, 11]. 이 렌더 트리는 화면에 실제로 그려지는 가시적인 노드만을 포함하며, `<head>` 태그나 `display: none` 스타일이 적용된 DOM 노드는 렌더 트리에 포함되지 않습니다 [4, 5, 12, 13].
* **DOM 조작과 렌더링 성능([[Reflow & Repaint|Reflow & Repaint]]):** DOM 노드의 수가 많고 깊이가 깊을수록 레이아웃 및 페인트와 같은 후속 렌더링 단계에 걸리는 연산 부담이 크게 증가합니다 [2, 3, 10, 14]. 또한, JavaScript로 DOM의 구조를 추가/삭제하거나 크기, 위치 속성을 변경하면 브라우저는 화면의 레이아웃을 다시 계산하는 Reflow(또는 Layout)를 실행하고, 이어 픽셀을 다시 그리는 Repaint 단계를 거치게 되어 막대한 연산 비용이 발생합니다 [7, 14-17].
* **성능 최적화 및 접근 최소화 방법:** DOM 조작으로 인한 성능 저하를 막기 위해 DOM 노드나 속성값을 변수에 캐싱(Caching)하여 재사용하거나, 연산을 반복문 외부로 빼내어 DOM 상호작용 횟수를 최소화해야 합니다 [18, 19]. 특히, DOM 값을 읽는 작업(Phase 1)과 수정하는 작업(Phase 2)을 교차로 수행하는 레이아웃 스래싱([[Layout Thrashing|Layout Thrashing]])을 방지하도록 코드를 분리하는 것이 중요합니다 [19-21].
* **React의 Virtual DOM 도입 배경:** 위와 같은 직접적인 DOM 조작의 비효율성을 극복하기 위해 React는 메모리상에 존재하는 가벼운 복사본인 Virtual DOM(VDOM)을 도입했습니다 [7, 22]. 상태가 변경되면 React는 새로운 Virtual DOM을 생성하고 이전과 비교(Diffing/[[Reconciliation|Reconciliation]])하여 변경된 최소한의 부분만을 실제 DOM에 반영함으로써 렌더링 성능을 극대화합니다 [7, 22, 23].
## 🔗 Knowledge Connections
- **Related Topics:** [[Virtual DOM|Virtual DOM]], CSSOM, Render Tree, [[Reflow 및 Repaint|Reflow 및 Repaint]], [[Critical Rendering Path (CRP)|Critical Rendering Path (CRP]]
- **Projects/Contexts:** [[React 렌더링 최적화|React 렌더링 최적화]], 브라우저 렌더링 과정, [[웹 성능 가이드(Web Performance)|웹 성능 가이드(Web Performance]]
- **Contradictions/Notes:** DOM의 구축은 HTML 데이터를 수신함과 동시에 '점진적(incremental)'으로 이루어지며 렌더링을 차단하지 않는 반면, 스타일을 정의하는 CSSOM의 구축은 후속 규칙이 이전 규칙을 덮어쓸 수 있기 때문에 완전히 구문 분석될 때까지 렌더링을 차단(render-[[Blocking|Blocking]])한다는 점에서 작동 방식의 차이가 있습니다 [2, 8-10].
---
*Last updated: 2026-04-25*
@@ -1,33 +0,0 @@
# [[Design System Architecture|DesignSystem Architecture]]
## 📌 Brief Summary
디자인 시스템 아키텍처는 재사용 가능한 UI 컴포넌트, 디자인 토큰(색상, 타이포그래피, 간격 등), 그리고 이들을 조합하는 규칙들의 집합으로, 일관되고 접근성 높은 애플리케이션을 신속하게 구축할 수 있게 해주는 프레임워크입니다 [1, 2]. 이는 엔지니어, 디자이너, 제품 관리자 간의 공통 언어로 기능하며 팀의 생산성을 높입니다 [3, 4]. 현대 프론트엔드 환경에서는 런타임 성능 최적화, 다계층 디자인 토큰 시스템, 그리고 모듈화된 컴포넌트 아키텍처의 융합을 통해 확장 가능하고 유지보수가 쉬운 대규모 UI 시스템을 구현하는 것이 핵심입니다 [5].
## 📖 Core Content
* **디자인 토큰 시스템 (Design Token Systems)**
디자인 시스템의 근간을 이루는 디자인 토큰은 확장성과 일관성을 위해 3단계 계층 구조로 관리됩니다 [2, 6].
* **원시/기본 토큰 (Primitive/Base Tokens):** 헥스 코드나 픽셀 단위와 같은 시스템의 근본적인 원시 값입니다 (예: `color.blue.500`) [7-9].
* **시맨틱 토큰 (Semantic Tokens):** 목적과 의도를 나타내며 기본 토큰을 참조합니다. 런타임 환경에서 다크 모드 등 테마 스위칭을 안전하게 지원하는 핵심 역할을 합니다 (예: `color.primary`) [7-9].
* **컴포넌트 토큰 (Component Tokens):** 특정 UI 컴포넌트나 변형에 종속되는 토큰으로, 시맨틱 토큰을 참조하여 복잡한 UI 상태를 관리합니다 [7, 9].
* **컴포넌트 라이브러리 아키텍처 패턴 (Component [[Architecture|Architecture]] Patterns)**
* **아토믹 디자인 ([[Atomic Design|Atomic Design]]):** UI를 원자(Atoms), 분자(Molecules), 유기체(Organisms), 템플릿(Templates), 페이지(Pages) 단위로 분해하여 재사용성을 극대화하는 멘탈 모델입니다 [10, 11].
* **복합 컴포넌트 ([[Compound Components|Compound Components]]):** 탭(Tabs)이나 아코디언(Accordion) 등에서 컴포넌트 간 Context를 통해 상태를 암시적으로 공유하여, 과도한 [[Prop Drilling|Prop Drilling]](Prop Soup)을 방지하고 유연한 레이아웃을 제공합니다 [12-14].
* **헤드리스 UI ([[Headless Components|Headless Components]]):** 상태 관리, 접근성(A11y) 등 비즈니스 로직만 제공하고 렌더링 형태(UI)는 개발자에게 맡기는 방식으로, [[Tailwind CSS|Tailwind CSS]]와 결합하여 고도로 커스터마이징 가능한 시스템을 구축할 때 적합합니다 [15].
* **오버라이드 패턴 ([[Overrides Pattern|Overrides Pattern]]):** Uber의 Base Web 등에서 사용되며, 컴포넌트를 구성하는 세부 하위 요소에 새로운 속성이나 스타일을 주입하거나 컴포넌트 전체를 교체할 수 있는 구조를 제공합니다 [16-18].
* **스타일링 패러다임 비교 ([[styled-components|styled-components]] vs Tailwind CSS)**
* **Styled-Components ([[CSS-in-JS|CSS-in-JS]]):** 컴포넌트 단위의 강한 응집력과 동적 스타일링을 제공하지만, JavaScript 실행에 따른 런타임 오버헤드가 발생합니다 [19, 20]. 특히 React Server Components (RSC 환경에서는 Context 접근이 불가하므로 [[Style Registry|Style Registry]] 등 부가적인 설정이 필요하며 하이드레이션 불일치 위험이 따릅니다 [21-23].
* **Tailwind CSS:** 유틸리티 퍼스트 접근법으로, 최신 v4 버전에서는 `@theme` 디렉티브 기반의 CSS-first 아키텍처를 도입해 디자인 토큰을 기본 CSS 변수로 직접 노출합니다 [24-26]. 런타임 오버헤드가 0에 수렴하는 정적 CSS를 생성하여 TTI(Time to Interactive), INP(Interaction to Next Paint) 등 [[Core Web Vitals|Core Web Vitals]] 성능 개선에 압도적으로 유리합니다 [20, 27-29].
* **대규모 프론트엔드 시스템 확장 및 거버넌스 ([[Scalability|Scalability]] & Governance)**
* **[[Monorepo|Monorepo]] & FSD:** Turborepo나 Nx 같은 모노레포 환경과 결합하여 [[Feature-Sliced Design|Feature-Sliced Design]] (FSD) 계층 구조를 채택하면, 제네릭 컴포넌트(Shared)와 비즈니스 피처(Features) 간의 의존성을 한 방향으로 엄격하게 통제할 수 있습니다 [30-32].
* **자동화 및 관측성 (Observability):** Uber의 uSpec처럼 AI를 활용해 [[Figma|Figma]]에서 컴포넌트 스펙을 추출해 다중 플랫폼 문서를 자동화하거나, 앱 내 Base 컴포넌트 채택률을 결정론적 방식(Deterministic Counter)으로 측정하여 스타일 편차(Style drift)를 방지하는 모니터링 시스템을 구축하는 것이 엔터프라이즈급 관리의 핵심입니다 [33-38].
## 🔗 Knowledge Connections
- **Related Topics:** [[Design Tokens|Design Tokens]], Atomic Design, Compound Components, [[Tailwind CSS|Tailwind CSS]], Styled-Components, [[Feature-Sliced Design (FSD)|Feature-Sliced Design (FSD]]
- **Projects/Contexts:** [[React Server Components (RSC)|React Server Components (RSC]], Uber Base Web, [[Shopify Polaris|Shopify Polaris]]
- **Contradictions/Notes:** 컴포넌트의 스타일링 방식에 있어, Styled-Components와 같은 CSS-in-JS는 뛰어난 컴포넌트 개발 경험(DX)과 동적인 테마 적용의 이점을 제공한다고 주장되지만, 대규모 서비스 성능 관점에서는 런타임 처리 비용과 [[React Server Components|React Server Components]](RSC) 환경에서의 제약 때문에 Tailwind CSS와 같은 빌드 타임(Static) 유틸리티 모델이 더 우수하다는 강력한 성능적 반론이 존재합니다 [19-21, 29, 39, 40].
---
*Last updated: 2026-04-26*
@@ -1,23 +0,0 @@
# [[Design Systems|DesignSystems]]
## 📌 Brief Summary
디자인 시스템(Design Systems)은 색상, 간격 등의 시각적 디자인 정보를 담은 디자인 토큰([[Design Tokens|Design Tokens]])과 규칙, 재사용 가능한 컴포넌트들의 집합입니다[1]. 이는 엔지니어, 디자이너, 프로덕트 매니저가 일관성 있고 접근성이 뛰어난 애플리케이션을 빠르고 효율적으로 구축할 수 있도록 돕는 공통 언어 역할을 합니다[2]. 디자인 시스템을 도입하면 스타일의 파편화를 막고, 다크 모드나 다중 브랜드 테마와 같은 글로벌 변경 사항을 런타임 또는 빌드 타임에 안전하고 동적으로 확장할 수 있습니다[3-5].
## 📖 일Core Content
* **디자인 토큰(Design Tokens)의 계층적 구조**: 확장 가능한 UI 아키텍처의 핵심인 디자인 토큰은 JSON이나 YAML과 같은 기계 판독형 형식으로 저장되어 코드와 디자인 툴을 자동으로 동기화합니다[4, 6]. 유지보수성과 확장성을 높이기 위해 토큰은 3단계 계층 구조를 가집니다. 즉, 순수 값을 나타내는 기본 토큰(Primitive/Base Tokens), 사용 목적과 맥락을 부여한 시맨틱 토큰(Semantic Tokens), 개별 컴포넌트 변형에 쓰이는 컴포넌트 토큰(Component Tokens)으로 구성됩니다[7-12].
* **리액트(React) 스타일링 패러다임 비교**:
* **[[styled-components|styled-components]]**: 컴포넌트에 직접 스타일을 캡슐화하여 동적이고 props에 기반한 스타일링을 제공하는 CSS-in-JS 방식입니다[13, 14]. 하지만 브라우저에서 JavaScript를 실행하여 스타일을 주입하므로 런타임 오버헤드가 발생하며, [[React Context|React Context]]가 없는 [[React Server Components|React Server Components]](RSC) 환경에서는 서버 렌더링에 취약하다는 단점이 있습니다[15-18].
* **[[Tailwind CSS|Tailwind CSS]]**: 유틸리티 퍼스트(Utility-first) 접근법을 취하며, 정적 CSS를 빌드 타임에 생성하여 런타임 오버헤드가 전혀 없습니다[19, 20]. 특히 Tailwind v4는 `@theme` 지시어와 네이티브 CSS 변수를 사용하는 CSS 우선 아키텍처로 전환되어, 빌드 속도 및 초기 렌더링([[Core Web Vitals|Core Web Vitals]]) 성능 면에서 CSS-in-JS보다 대규모 확장에 매우 유리합니다[18, 21-23].
* **재사용 가능한 컴포넌트 아키텍처 설계 패턴**:
* **아토믹 디자인([[Atomic Design|Atomic Design]])**: UI를 원자(Atoms), 분자(Molecules), 유기체(Organisms), 템플릿(Templates), 페이지(Pages)의 5단계로 세분화하여, 예측 가능하고 조립 가능한 컴포넌트 라이브러리를 구축하는 기초 방법론입니다[24-28].
* **컴파운드 컴포넌트([[Compound Components|Compound Components]])**: 단일 컴포넌트에 너무 많은 속성(Prop)을 주입해 복잡해지는 문제를 해결하기 위해, 여러 하위 컴포넌트가 내부적으로 상태(Context)를 공유하도록 선언적으로 구성하는 패턴입니다(예: `Accordion.Root`, `Accordion.Item`)[29-32].
* **오버라이드 패턴(Overrides API) 및 헤드리스(Headless) 컴포넌트**: Uber의 Base Web 등에서 사용하는 오버라이드 패턴은 내부 요소의 기능이나 스타일을 사용자가 쉽게 교체할 수 있도록 합니다[33-36]. 헤드리스 컴포넌트는 스타일링을 제외한 상태 관리와 접근성 로직만을 제공하여 Tailwind 등과 결합 시 유연성을 극대화합니다[37].
* **대규모 프론트엔드의 구조화([[Monorepo|Monorepo]] 및 FSD)**: 시스템이 커질 경우, 단일 폴더에 공유 컴포넌트를 무분별하게 담지 않고 Monorepo 환경에서 [[Feature-Sliced Design|Feature-Sliced Design]] (FSD) 아키텍처를 도입하는 것이 권장됩니다[38-41]. FSD는 코드를 Shared, Entities, Features, Widgets, Pages 등으로 명확히 분리하여 의존성의 방향을 통제하고 퍼블릭 API 캡슐화를 강제하여 시스템을 견고하게 유지합니다[39, 41].
## 🔗 Knowledge Connections
- **Related Topics:** [[Design Tokens|Design Tokens]], Atomic Design, Compound Components, [[Tailwind CSS|Tailwind CSS]], Styled-components, [[Feature-Sliced Design|Feature-Sliced Design]]
- **Projects/Contexts:** [[Shopify Polaris|Shopify Polaris]], [[Uber Base Web|Uber Base Web]]
- **Contradictions/Notes:** 소스 [42]와 [43]는 Tailwind CSS를 사용할 때 여러 유틸리티 클래스로 인해 마크업이 매우 길어지고(Class Soup) 가독성이 떨어질 수 있다고 지적하지만, 소스 [44]와 [45]은 이를 방지하기 위해 유틸리티 클래스를 반복 작성하는 대신 "재사용 가능한 컴포넌트"로 추상화하거나 플러그인 기반 시스템을 구축해야 한다고 조언합니다. 또한 소스 [14], [18]은 Styled-components가 훌륭한 개발자 경험과 동적 스타일링을 제공한다고 설명하지만, 소스 [15], [16], [17]은 대규모 앱이나 RSC가 적용된 [[Next.js|Next.js]] 환경에서는 런타임 성능 및 호환성 이슈를 야기할 수 있으므로 Tailwind나 [[CSS Modules|CSS Modules]]를 권장하며 서로 다른 최적의 사용 사례를 제시합니다.
---
*Last updated: 2026-04-26*
@@ -1,21 +0,0 @@
# [[Design Tokens|Design Tokens]]
## 📌 Brief Summary
디자인 토큰(Design Tokens)은 색상, 서체, 간격, 그림자, 모션 등 사용자 인터페이스의 시각적 DNA를 구성하는 원자 단위의 데이터 포인트입니다 [1-3]. 이 데이터는 JSON이나 YAML과 같은 기계 판독 가능한 형식으로 저장되어 디자인 도구와 코드를 자동으로 연결하는 단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]]) 역할을 합니다 [1, 4, 5]. 디자인 토큰은 하드코딩된 값을 대체함으로써 UI 구성 요소의 일관성을 유지하고, 다크 모드와 같은 동적 테마를 효율적으로 전환하며, React 프로젝트에서 확장 가능한 디자인 시스템을 구축하는 데 핵심적인 역할을 수행합니다 [6-8].
## 📖 Core Content
* **디자인 토큰의 3계층 구조:** 확장 가능하고 안전한 시스템을 구축하기 위해 디자인 토큰은 3단계 계층으로 구성됩니다 [9-11].
* **원시/기본 토큰 (Primitive/Base Tokens):** `#3366FF``16px`과 같은 구체적이고 원시적인 값으로, 시맨틱(의미론적)인 목적을 갖지 않는 디자인 시스템의 기본 구성 요소입니다 [10, 12-14].
* **시맨틱/앨리어스 토큰 (Semantic/Alias Tokens):** 원시 토큰을 참조하여 디자인의 '의도'와 역할을 명시합니다 (예: `color.primary = color.blue.500`) [10, 12-14]. 안전한 리팩토링과 테마 전환을 가능하게 하는 가장 중요한 계층입니다 [10, 12].
* **컴포넌트 토큰 (Component Tokens):** 특정 컴포넌트와 그 변형에 직접적으로 연결된 토큰입니다 (예: `button.background = color.primary`) [10-14].
* **동적 테마 및 도구 통합:** 디자인 토큰을 활용하면 별도의 테마 토큰 세트(예: Light/Dark 모드)를 정의하여 **동적 테마([[Dynamic Theming|Dynamic Theming]])**를 쉽게 구현할 수 있습니다 [15, 16]. [[Style Dictionary|Style Dictionary]]와 같은 도구를 사용하면 JSON에 정의된 토큰을 CSS Custom Properties(CSS 변수)나 iOS, Android, React용 포맷으로 자동 변환하여 코드 베이스에 즉시 주입할 수 있습니다 [17-20].
* **[[Tailwind CSS v4|Tailwind CSS v4]]와의 시너지:** Tailwind CSS v4는 구성 방식에 있어 [[JavaScript|JavaScript]] 파일 대신 CSS 우선(CSS-first) 구조를 도입하여 토큰 관리에 패러다임 전환을 가져왔습니다 [21-23]. `@theme` 디렉티브 내에서 디자인 토큰을 기본 CSS 변수로 정의하면, Tailwind가 이에 대응하는 유틸리티 클래스를 자동으로 생성합니다(예: `--color-primary-500` 선언 시 `bg-primary-500` 사용 가능) [21-24]. 이를 통해 CSS 변수를 네이티브하게 활용할 수 있고, JS 오버헤드 없이 강력한 런타임 테마 기능을 제공합니다 [23, 25, 26].
* **협업 효율성 및 확장성:** 디자인 토큰은 디자이너와 프론트엔드 개발자 간에 공통된 언어를 형성하여 중복된 스타일링을 방지하고 코드의 유지보수 비용을 낮춥니다 [8, 27-29]. 중앙 집중식 토큰 관리를 통해 CI/CD 파이프라인에서 토큰의 배포를 자동화하면 대규모 React 애플리케이션에서도 시각적 일관성을 깨뜨리지 않고 스타일을 안정적으로 진화시킬 수 있습니다 [30-33].
## 🔗 Knowledge Connections
- **Related Topics:** `[[CSS Variables|CSS Variables]]`, `Tailwind CSS v4`, `Style Dictionary`, `[[Dynamic Theming|Dynamic Theming]]`
- **Projects/Contexts:** `[[Figma Tokens Studio|Figma Tokens Studio]]`, `React Component Architecture`, `[[Uber Base Web Design System|Uber Base Web Design System]]`
- **Contradictions/Notes:** 소스의 권장 사항에 따르면, 개발 시 컴포넌트에 원시 토큰(Primitive Tokens)이나 임의의 값을 직접 하드코딩하는 것은 시스템의 확장성을 파괴하는 주된 원인이 됩니다 [34, 35]. 따라서 스타일의 일관성을 유지하고 유연한 테마를 지원하기 위해서는 반드시 시맨틱 토큰(Semantic Tokens)을 거쳐 컴포넌트에 적용해야 합니다 [10, 34, 36].
---
*Last updated: 2026-04-26*
@@ -1,27 +0,0 @@
# [[Diffing Algorithm|Diffing Algorithm]]
## 📌 Brief Summary
Diffing Algorithm(디핑 알고리즘)은 React에서 이전 가상 DOM([[Virtual DOM|Virtual DOM]]) 트리와 새롭게 계산된 트리를 비교하여 실제 DOM을 가장 효율적으로 업데이트할 방법을 결정하는 과정입니다 [1, 2]. 이론적인 트리 비교 알고리즘은 $O(n^3)$의 시간 복잡도를 가져 실시간 애플리케이션에 부적합하지만, React는 두 가지 휴리스틱 가정을 통해 이를 $O(n)$ 복잡도로 최적화했습니다 [3-5]. 이 알고리즘은 '[[Reconciliation|Reconciliation]](재조정)' 과정의 핵심으로, 불필요한 DOM 조작을 최소화하여 렌더링 성능을 극대화하는 역할을 합니다 [1, 2, 6].
## 📖 Core Content
* **알고리즘의 기본 원리 및 가정:**
React의 디핑 알고리즘은 두 가지 주요 가정에 기반하여 $O(n)$의 성능을 달성합니다. 첫째, 서로 다른 타입의 요소는 근본적으로 다른 트리를 생성한다고 가정합니다 [3, 5]. 둘째, 개발자가 제공하는 `key` prop을 통해 여러 렌더링 사이클 동안 안정적으로 유지되는 자식 요소를 식별할 수 있다고 가정합니다 [3, 5].
* **비교(Diffing) 프로세스 메커니즘:**
* **다른 타입의 요소:** 루트 요소의 타입이 다를 경우(예: `<a>`에서 `<img>`로 변경), React는 이전 트리를 완전히 허물고 처음부터 새로운 트리를 구축합니다. 이 과정에서 기존 DOM 노드와 연관된 컴포넌트의 상태([[State|State]])는 모두 파괴됩니다 [7, 8].
* **동일한 타입의 DOM 요소:** 두 요소의 속성을 비교하여 동일한 기본 DOM 노드를 유지한 채 변경된 속성(예: `className`, `color``fontWeight` 같은 `style` 등)만 업데이트합니다 [9, 10].
* **동일한 타입의 컴포넌트 요소:** 컴포넌트의 인스턴스가 동일하게 유지되어 상태가 보존됩니다. 새로운 요소에 맞게 prop이 업데이트된 후, 하위 요소들에 대해 재귀적으로 디핑 알고리즘을 수행합니다 [10, 11].
* **자식 요소의 재귀적 처리와 Key의 역할:**
기본적으로 React는 두 하위 요소 목록을 동시에 반복하면서 차이가 있을 때마다 변이를 생성합니다 [11]. 하지만 리스트의 맨 앞에 요소를 추가하는 경우 등 순서가 변경될 때는 전체를 다시 렌더링하는 매우 비효율적인 상황이 발생할 수 있습니다 [12]. 이를 해결하기 위해 고유한 `key` 속성을 사용하면, React는 기존 트리와 새 트리의 자식들을 일치시켜 이동한 요소만 파악하므로 불필요한 DOM 재생성을 방지할 수 있습니다 [12, 13].
* **트레이드오프 및 주의사항:**
이 알고리즘은 휴리스틱에 의존하기 때문에 가정이 충족되지 않으면 성능이 저하될 수 있습니다 [14]. 예를 들어 하위 트리가 형제 요소 사이가 아닌 아예 다른 계층으로 이동하는 경우, 알고리즘은 해당 하위 트리를 완전히 다시 렌더링합니다 [15]. 또한 배열의 인덱스를 키로 사용하거나 `Math.random()` 같은 불안정한 키를 사용하면 리스트가 재정렬될 때 컴포넌트 상태가 꼬이거나 성능 저하가 발생할 수 있습니다 [14, 16].
## 🔗 Knowledge Connections
- **Related Topics:** [[Virtual DOM|Virtual DOM]], Reconciliation, [[React Fiber|React Fiber]]
- **Projects/Contexts:** [[React Frontend Development|React Frontend Development]], [[Component-Based Architecture|Component-Based Architecture]]
- **Contradictions/Notes:** 일반적인 트리 비교 알고리즘은 $O(n^3)$의 복잡도를 가지지만, React의 디핑 알고리즘은 휴리스틱([[Heuristics|Heuristics]])을 적용하여 실용적인 $O(n)$ 복잡도로 구현되었다는 점이 핵심적인 기술적 차이입니다 [4, 5]. 배열의 인덱스를 `key`로 사용하는 것은 요소의 순서가 변경되지 않을 때만 유효하며, 재정렬(Reorder) 시에는 비효율적이고 상태 오류를 일으킬 수 있으므로 권장되지 않습니다 [13, 16].
---
*Last updated: 2026-04-25*
@@ -1,17 +0,0 @@
# [[Downshift|Downshift]]
## 📌 Brief Summary
Down[[Shift|Shift]]는 React 환경에서 `useCombobox()`와 같은 기능을 제공하는 헤드리스 컴포넌트([[Headless Components|Headless Components]]) 라이브러리의 대표적인 예시입니다 [1]. 이 라이브러리는 컴포넌트의 내부 상태와 로직만을 노출하고, 실제 UI 마크업의 형태는 개발자가 전적으로 정의하도록 위임합니다 [1]. 이를 통해 특정 디자인에 얽매이지 않고 접근성 높은 UI 라이브러리를 구축할 수 있도록 돕습니다 [1].
## 📖 Core Content
* **헤드리스 컴포넌트(Headless Components) 패턴:** Downshift는 UI 마크업 없이 로직만을 제공하는 헤드리스 컴포넌트의 특징을 잘 보여줍니다 [1]. 개발자는 Downshift가 제공하는 로직을 바탕으로 자신이 원하는 대로 시각적 요소를 구현할 수 있습니다 [1].
* **로직과 마크업의 완벽한 분리:** 상태 및 동작 로직을 UI 마크업과 철저히 분리하기 때문에 구성 요소의 조합성(Composability)이 매우 뛰어납니다 [1].
* **뛰어난 확장성과 호환성:** 특정한 스타일이나 마크업을 강제하지 않으므로 어떠한 디자인 시스템과도 완벽하게 호환되며, 프레임워크에 구애받지 않는(framework-agnostic) 확장 가능한 컴포넌트를 구축하는 데 매우 적합합니다 [1].
## 🔗 Knowledge Connections
- **Related Topics:** [[Headless Components|Headless Components]], React Component Patterns, [[Accessible UI Libraries|Accessible UI Libraries]]
- **Projects/Contexts:** [[Design Systems|DesignSystems]], 확장 가능하고 유지보수하기 쉬운 프론트엔드 UI 컴포넌트 아키텍처 구축 [1].
- **Contradictions/Notes:** 소스에 관련 정보가 부족합니다.
---
*Last updated: 2026-04-26*
@@ -1,18 +0,0 @@
# [[Dynamic Theming|Dynamic Theming]]
## 📌 Brief Summary
Dynamic Theming(동적 테마 적용)은 라이트 모드/다크 모드 또는 다중 브랜드 테마와 같이 사용자 설정이나 컨텍스트에 따라 UI의 시각적 속성을 런타임에 유연하게 전환할 수 있는 기법입니다. 이는 주로 디자인 토큰([[Design Tokens|Design Tokens]]), CSS 변수(Custom Properties), 또는 styled-components와 같은 [[CSS-in-JS|CSS-in-JS]] 라이브러리를 활용하여 구현됩니다. 컴포넌트 코드의 직접적인 수정 없이 애플리케이션 전체의 디자인 시스템을 일관성 있고 확장 가능하게 관리하는 데 필수적인 역할을 합니다.
## 📖 Core Content
* **디자인 토큰 기반의 테마 전환 (Token Swapping):** 동적 테마 구현의 핵심은 단일 소스인 디자인 토큰을 활용하는 것입니다. 특정 시맨틱 토큰(Semantic Token)이 테마에 따라 다른 참조 값([[Reference|Reference]] Value)을 가리키도록 설정합니다(예: 라이트 모드에서는 `color.background = ref.gray.100`, 다크 모드에서는 `ref.gray.900`) [1]. Style Dictionary와 같은 도구를 활용하면 [[Figma|Figma]] 등에서 정의된 JSON 형식의 토큰을 CSS 변수나 React 테마 객체로 자동 변환하여 손쉽게 테마 전용 출력물을 생성할 수 있습니다 [2-4].
* **CSS 변수([[CSS Variables|CSS Variables]])를 활용한 동적 테마:** 최적의 성능을 위해 디자인 토큰을 CSS 변수에 매핑하여 사용하는 방식이 널리 쓰입니다 [5]. 테마별로 별도의 토큰 세트를 정의하고(예: `light-theme.css`, `dark-theme.css`), 런타임 시에 `<html>` 또는 `<body>` 같은 최상위 컨테이너에 테마 클래스를 토글하여 스타일을 업데이트할 수 있습니다 [5, 6]. 이 접근법은 값비싼 전체 리렌더링(full re-render)을 유발하지 않아 부드럽고 빠른 사용자 경험을 제공합니다 [5, 7]. 최근 [[Tailwind CSS v4|Tailwind CSS v4]]에서도 `@theme` 디렉티브와 CSS 변수를 활용해 네이티브 수준의 런타임 테마 전환을 직관적으로 지원합니다 [8, 9].
* **React 프레임워크 및 CSS-in-JS의 테마 적용:** `styled-components``Emotion` 같은 CSS-in-JS 라이브러리는 기본적으로 제공하는 `ThemeProvider`를 사용해 React 컴포넌트 트리에 동적으로 테마를 주입할 수 있어 다중 테마 구현에 매우 용이합니다 [10, 11]. 또한, `Chakra UI`는 CSS-in-JS를 기반으로 제작되어 런타임 시 라이트/다크 모드 동적 전환을 쉽게 구현할 수 있도록 돕습니다 [12].
* **[[React Server Components (RSC)|React Server Components (RSC]] 환경에서의 제약과 해법:** Context 기반의 `ThemeProvider`는 React Context가 없는 서버 컴포넌트(RSC) 환경에서는 작동하지 않는 근본적인 한계가 있습니다 [13-15]. 이를 해결하기 위해 `styled-components` (v6.4 이상)는 `createTheme` 함수를 도입하여 일반 테마 객체를 CSS 사용자 정의 속성 참조(예: `var(--prefix-path)`)로 변환합니다 [13]. 이 방식은 React Context에 의존하지 않으므로 클라이언트와 서버 컴포넌트 모두에서 동작하며, 라이트/다크 모드 전환 시 하이드레이션([[Hydration|Hydration]]) 불일치나 화면 깜빡임(Flash)을 방지합니다 [13, 16].
## 🔗 Knowledge Connections
- **Related Topics:** [[Design Tokens|Design Tokens]], CSS Variables, Styled Components, [[Tailwind CSS|Tailwind CSS]], [[React Server Components (RSC)|React Server Components (RSC]]
- **Projects/Contexts:** [[Scalable Frontend Systems|Scalable FrontendSystems]], [[Component Library Architecture|Component Library Architecture]], Design-to-Code Workflow
- **Contradictions/Notes:** CSS-in-JS 라이브러리의 `ThemeProvider`는 동적인 테마 적용에 매우 유용하지만, [[Next.js|Next.js]]의 App Router와 같은 React Server Components(RSC) 아키텍처와는 본질적으로 호환되지 않습니다 [14, 15]. 최신 확장성 높은 프론트엔드 환경에서는 이러한 런타임 CSS-in-JS 대신 정적 생성된 CSS 변수나 Tailwind CSS, 혹은 제로 런타임 라이브러리([[vanilla-extract|vanilla-extract]]) 기반의 테마 시스템을 구축하는 것이 권장됩니다 [13, 15, 17, 18].
---
*Last updated: 2026-04-26*
@@ -1,22 +0,0 @@
# [[E-commerce Platforms|E-commerce Platforms]]
## 📌 Brief Summary
E-commerce Platforms(이커머스 플랫폼)은 제품 카탈로그, 장바구니, 결제 처리 등의 기능을 제공하여 온라인 상거래를 지원하는 시스템입니다 [1, 2]. 이 시스템의 핵심은 검색 엔진 최적화(SEO)를 통한 제품 발견, 빠른 페이지 로딩을 통한 구매 전환율 향상, 그리고 재고 및 가격 변동을 반영하는 최신 데이터의 유지입니다 [3-5]. 소스 자료에 따르면, 이커머스 플랫폼은 성능과 확장성을 극대화하기 위해 SSR(서버 사이드 렌더링), ISR(점진적 정적 재생성)과 같은 최적화된 웹 렌더링 전략과 컴포넌트 기반 아키텍처(CBA)를 적극적으로 채택합니다 [2, 6].
## 📖 Core Content
* **이커머스 플랫폼을 위한 웹 렌더링 전략 (Web Rendering Strategies):**
* **SSR (Server-Side Rendering):** 이커머스 플랫폼의 제품 목록 페이지, 카테고리 탐색 및 개별 제품 상세 페이지에 가장 이상적인 렌더링 방식 중 하나입니다 [3]. 서버에서 제품의 세부 정보, 가격, 구매 버튼이 포함된 완전한 HTML을 즉시 제공하므로, 자바스크립트 로딩을 기다릴 필요 없이 사용자에게 콘텐츠를 보여주어 구매 전환율을 크게 향상시킵니다 [5]. 또한 훌륭한 SEO를 제공하여 제품 검색 노출에 유리하며, 항상 최신의 실시간 데이터를 요구하는 결제(Checkout) 페이지에 적합합니다 [3, 7].
* **SSG (Static Site Generation):** 제품 라인이 변동 없이 안정적이고 콘텐츠 업데이트 주기가 규칙적인 제품 카탈로그 페이지에 적용될 수 있습니다 [8].
* **ISR (Incremental Static Regeneration):** 이커머스 플랫폼에 최적의 균형(성능과 최신성)을 제공하는 고도화된 접근 방식입니다 [4, 6]. 대규모 제품 카탈로그를 초고속으로 로딩하는 동시에, 전체 사이트를 다시 빌드하는 오버헤드 없이 백그라운드에서 재고 정보와 가격을 주기적으로 업데이트하여 최신 상태로 유지할 수 있습니다 [4, 6, 9].
* **컴포넌트 기반 아키텍처 적용 ([[Component-Based Architecture|Component-Based Architecture]]):**
* 이커머스 플랫폼은 제품 목록(Product listings), 결제 게이트웨이(Payment gateways), 장바구니(Shopping c[[Arts|Arts]]), 고객 리뷰 모듈 등 명확히 분리된 기능을 가진 재사용 가능한 소프트웨어 컴포넌트들의 조립으로 구축됩니다 [2].
* 이러한 모듈식 접근 방식을 통해 비즈니스가 확장됨에 따라 새로운 결제 옵션을 추가하거나 제품 추천 기능을 갱신해야 할 때, 플랫폼 전체에 중단을 일으키지 않고 특정 컴포넌트만 쉽게 교체하거나 확장할 수 있는 유연성을 확보합니다 [2, 10].
## 🔗 Knowledge Connections
- **Related Topics:** [[Server-Side Rendering (SSR)|Server-Side Rendering (SSR]], Incremental Static Regeneration (ISR), Component-Based Architecture, Search Engine Optimization (SEO
- **Projects/Contexts:** 대규모 트래픽을 처리하면서도 검색 엔진 노출을 극대화하고 실시간 재고/가격 변동을 반영해야 하는 프론트엔드 웹 성능 최적화 및 렌더링 아키텍처 구축 맥락 [3, 4, 7].
- **Contradictions/Notes:** 제공된 소스는 이커머스 플랫폼의 백엔드 비즈니스 로직이나 운영 모델보다는 주로 프론트엔드의 화면 렌더링 최적화(SSR/ISR)와 아키텍처(컴포넌트화) 측면에 초점을 맞추고 있어, 결제 시스템의 내부 동작 원리 등에 대해서는 소스에 관련 정보가 부족합니다.
---
*Last updated: 2026-04-25*
@@ -1,42 +0,0 @@
## 📌 Brief Summary
Error Boundaries는 React 컴포넌트 트리 하위에서 발생하는 JavaScript 런타임 에러를 포착하여 전체 애플리케이션의 크래시(White Screen)를 방지하는 선언적 에러 처리 메커니즘이다. 에러가 발생한 지점을 격리하고 대체 UI(Fallback UI)를 렌더링함으로써 시스템의 가용성과 사용자 경험을 보호한다.
## 📖 Core Content
1. **작동 메커니즘 및 클래스 컴포넌트 의존성**
- React 16부터 도입되었으며, 자식 컴포넌트의 렌더링, 수명 주기 메서드, 생성자 내부의 에러를 감지한다.
- 반드시 클래스 컴포넌트로 구현해야 하며, `static getDerivedStateFromError()`로 상태를 업데이트하고 `componentDidCatch()`로 에러를 로깅한다.
2. **선언적 에러 격리 (Isolation)**
- 명령형 `try/catch`와 달리 React의 선언적 특성을 유지하며 컴포넌트 트리 수준에서 에러를 관리한다.
- 애플리케이션 전체가 아닌, 실패 위험이 높은 특정 위젯(차트, 서드파티 폼 등)을 독립된 Boundary로 감싸 '장애 격리'를 실현한다.
3. **포착 불가능한 영역 (Limitations)**
- 이벤트 핸들러, 비동기 코드(setTimeout, Fetch), 서버 사이드 렌더링(SSR), Error Boundary 자체 내의 에러는 포착하지 못한다.
- 이러한 영역은 여전히 `try/catch`나 전역 에러 핸들러를 통한 보완이 필요하다.
4. **미처리 에러의 결과**
- 포착되지 않은 에러는 전체 컴포넌트 트리의 마운트 해제(Unmounting)를 유발하며, 이는 손상된 데이터가 사용자에게 노출되는 것보다 안전한 선택으로 간주된다.
## ⚖️ Trade-offs & Caveats
- **클래스 컴포넌트 유지 필요성**: 최신 React가 Hooks 중심임에도 불구하고 Error Boundary 구현을 위해 클래스 컴포넌트를 유지해야 하는 아키텍처적 일관성 저하가 발생할 수 있다.
- **성능 및 렌더링 오버헤드**: 너무 많은 Error Boundary를 중첩할 경우 트리 깊이가 깊어지고 에러 전파 체크 로직에 따른 미세한 성능 영향이 있을 수 있다.
- **비동기 에러 처리의 공백**: 렌더링 에러만 포착하므로, 비동기 데이터 통신이 빈번한 현대 앱에서는 `react-error-boundary`와 같은 라이브러리를 통한 추가 처리가 필수적이다.
## 🔗 Knowledge Connections
### Related Concepts
- **Fallback UI**: 에러 발생 시 사용자에게 노출되는 방어적 인터페이스 (관계: 출력 결과물)
- **Component Stack Traces**: 에러 발생 위치를 추적하는 런타임 정보 (관계: 디버깅 핵심 데이터)
- **Sentry / LogRocket**: 프로덕션 환경의 에러 수집 및 분석 플랫폼 (관계: 운영 모니터링 연동)
### Deeper Research Questions
1. React의 내부 Fiber 아키텍처는 Error Boundary를 만났을 때 어떻게 렌더링 작업을 중단하고 커밋 단계로 전이하는가?
2. 이벤트 핸들러 내의 에러를 Error Boundary로 강제 전파하기 위한 'setState' 트릭의 원리와 한계는?
3. `react-error-boundary` 라이브러리가 함수형 컴포넌트 환경에서 클래스 컴포넌트의 한계를 극복하는 방식은?
4. 단일 전역 Error Boundary와 다중 지역 Error Boundary 간의 메모리 사용량 및 리렌더링 범위 트레이드오프는?
5. 서버 사이드 렌더링(SSR) 환경에서 클라이언트 사이드 Error Boundary가 활성화되기 전의 에러는 어떻게 처리해야 하는가?
### Practical Application Contexts
- **결제 및 금융 모듈**: 입력 폼의 작은 렌더링 오류가 전체 결제 프로세스 마비로 이어지지 않도록 격리.
- **서드파티 위젯 통합**: 안정성이 검증되지 않은 외부 라이브러리 기반 컴포넌트를 Boundary로 보호.
### Adjacent Topics
- **Try/Catch Statement in JS**
- **Observability in Frontend**
- **Graceful Degradation Design**
@@ -1,23 +0,0 @@
# [[Feature-Driven Architecture|Feature-Driven Architecture]]
## 📌 Brief Summary
Feature-Driven [[Architecture|Architecture]](또는 기능 주도 아키텍처, [[Feature-Sliced Design|Feature-Sliced Design]])는 파일 유형이 아닌 실제 비즈니스 기능이나 도메인을 기준으로 프론트엔드 프로젝트 코드를 그룹화하는 구조 설계 방식입니다 [1-3]. 특정 기능에 필요한 UI 컴포넌트, 비즈니스 로직, 스타일(CSS)을 독립적인 기능 폴더(예: `features/`) 내에 함께 캡슐화하여 관리합니다 [4, 5]. 이를 통해 결합도를 낮추고 모듈 경계를 명확히 하여 대규모 애플리케이션에서의 유지보수성, 확장성 및 팀 간 병렬 협업을 획기적으로 개선합니다 [1, 3].
## 📖 Core Content
* **기능 기반의 코드 분리와 캡슐화**
초기 웹 개발이나 소규모 프로젝트에서 흔히 쓰이는 컴포넌트(components), 훅(hooks), 유틸(utils) 등 파일 유형별 폴더 그룹화 대신 비즈니스 기능이나 도메인을 기준으로 구조를 구성합니다 [3, 6]. 예를 들어, [[Next.js|Next.js]] 환경에서는 라우터 기능을 담당하는 폴더(`app/`)는 라우팅과 레이아웃 용도로만 최소화하여 사용하고, 실제 비즈니스 로직과 복잡한 상태 관리는 `features/` 디렉토리(예: `market-data`, `user-profile`, `auth`) 내부로 이동시킵니다 [4, 6]. 이러한 캡슐화는 버그 발생 시 개발자가 방대한 전역 폴더를 탐색할 필요 없이 해당 기능 폴더만 확인하게 해주어 문제 해결을 직관적으로 만듭니다 [4].
* **유지보수성 및 확장성 향상**
관심사의 분리([[_뇌와 팔다리의 분리_ - 관심사의 분리 (Separation of Concerns)|Separation of Concerns]])를 실현하는 이 구조는 대규모 프로젝트 확장에 매우 유리합니다 [2-4]. 기능 단위로 코드가 분리되어 있어 코드 소유권이 명확해지고, 여러 팀이 병렬로 작업하기 쉬워지며 리팩토링이 안전해집니다 [3]. 또한, 네트워크 호출 등 API 연동 로직도 기능 폴더 내의 전용 서비스로 묶어 두어 프론트엔드 요소와 백엔드 API 간의 의존성을 깔끔하게 분리할 수 있습니다 [4, 6].
* **CSS 구조 설계와의 강력한 시너지 (스타일 모듈화)**
기능 주도 아키텍처는 스타일 시스템의 확장성을 설계하는 데 필수적입니다 [7]. 비즈니스 관련 컴포넌트와 그에 연결된 [[CSS Modules|CSS Modules]], [[SCSS|SCSS]] 파일을 같은 기능 디렉토리 내에 함께 위치시킵니다(co-location) [5]. 이러한 모듈화는 애플리케이션에서 특정 기능을 삭제할 때 해당 기능의 스타일 코드 역시 자동으로 폐기될 수 있게 보장하여, 레거시 프로젝트에 쌓이기 쉬운 사용되지 않는 '유령 스타일(ghost styles)'이나 데드 코드의 축적을 방지합니다 [5].
전반적인 프로젝트 구조를 Feature-Sliced Design(FSD) 같은 기능 기반으로 구성하고, 개별 CSS 구조는 BEM 같은 방법론을 통해 관리하면 기술 부채를 크게 줄일 수 있는 강력한 아키텍처가 형성됩니다 [1, 8].
## 🔗 Knowledge Connections
- **Related Topics:** [[Feature-Sliced Design (FSD)|Feature-Sliced Design (FSD]], CSS Modules, [[BEM|BEM]]
- **Projects/Contexts:** [[Next.js Modular and Scalable Project Structure|Next.js Modular and Scalable Project Structure]], Large Frontend Projects
- **Contradictions/Notes:** 소스에 따르면 애플리케이션 초기에는 파일 유형별 구성이 빠르고 편할 수 있으나, 데이터 대시보드나 복잡한 사용자 흐름을 다루게 될수록 관리 불능 상태에 빠지게 됩니다. 따라서 프로젝트 장기 스케일링을 위해 일찍부터 Feature-Driven Architecture 멘탈 모델을 채택하는 것이 거대한 리팩토링의 두통을 막는 방법으로 강력하게 권장됩니다 [2, 6, 9].
---
*Last updated: 2026-04-26*
@@ -1,18 +0,0 @@
# [[Feature-Sliced Design (FSD)|Feature-Sliced Design (FSD]]
## 📌 Brief Summary
**[[Feature-Sliced Design|Feature-Sliced Design]] (FSD)**는 프런트엔드 시스템 내 앱과 패키지의 코드를 체계적으로 조직화하여 조직 전체의 일관성을 보장하도록 돕는 아키텍처 방법론입니다 [1]. 명확한 책임과 의존성 규칙을 가진 계층(Layer)으로 코드베이스를 나누어, 개발자가 코드가 어디에 위치해야 하고 어떻게 임포트되어야 하는지 예측할 수 있게 합니다 [1, 2]. 결과적으로 '전역 공유 폴더'가 무분별한 스파게티 코드의 쓰레기장으로 변하는 것을 방지하고, 리팩토링의 안전성을 확보하며 새로운 팀원의 온보딩 시간을 단축합니다 [1-3].
## 📖 Core Content
- **명확한 계층적 구조 (Layered Structure):** FSD는 코드베이스를 엄격한 책임에 따라 여러 계층으로 나눕니다. 일반적인 UI 컴포넌트나 헬퍼 함수, 디자인 토큰을 담는 가장 낮은 계층인 `Shared`부터 시작하여, 비즈니스 도메인을 나타내는 `Entities`, 사용자를 위한 비즈니스 로직(예: 결제 처리)을 담은 `Features`, 이러한 기능과 엔티티를 결합하는 `Widgets`, 전체 화면을 구성하는 `Pages`, 그리고 스타일 및 라우팅이 초기화되는 진입점인 `App`으로 구성됩니다 [1].
- **의존성 방향 및 공개 API (Dependencies & [[Public APIs|Public APIs]]):** FSD는 상위 계층이 하위 계층을 향해서만 의존성을 가지도록 방향성을 통제하며, 슬라이스(slice) 경계에서 명시적인 공개 API(Public APIs)를 노출할 것을 권장합니다 [4, 5]. 예를 들어, 앱은 패키지의 깊은 내부 파일을 직접 임포트해서는 안 되며(`index.ts` 등을 통해서만 접근), 기능(`Features`)은 의도된 공유 슬라이스가 없는 한 다른 기능을 직접 임포트하지 않아야 합니다 [4, 5].
- **도메인 주도 설계(DDD)의 구체화:** 프런트엔드 환경에서 도메인 주도 설계를 실용적인 파일 시스템으로 변환하는 것은 까다롭지만, FSD는 이를 구체적인 프로젝트 구조로 맵핑해 줍니다 [6]. 핵심 도메인 개념은 `entities/`에, 사용자 대면 기능은 `features/`에, 재사용 가능한 원시 요소는 `shared/`에 배치함으로써 도메인 경계를 디렉토리 및 임포트 수준에서 시각적으로 명확하게 드러냅니다 [6].
- **모노레포 아키텍처와의 시너지:** 모노레포([[Monorepo|Monorepo]]) 환경에서 FSD를 적용하면 UI 키트나 API 클라이언트 등은 공유 패키지로 분리하고, 각 앱과 도메인 패키지 내부는 FSD 계층에 따라 구조화하는 "두 세계의 장점(best of both worlds)"을 취할 수 있습니다 [7]. 이는 대규모 시스템에서 우발적인 결합(accidental coupling)을 크게 줄여줍니다 [4].
## 🔗 Knowledge Connections
- **Related Topics:** [[Monorepo Architecture|Monorepo Architecture]], Atomic Design, Domain-Driven Design (DDD), [[Public APIs|Public APIs]]
- **Projects/Contexts:** [[대규모 확장성과 유지보수성이 요구되는 프런트엔드 모노레포 프로젝트|대규모 확장성과 유지보수성이 요구되는 프런트엔드 모노레포 프로젝트]], [[Turborepo 및 Nx와 같은 빌드 오케스트레이션 도구를 활용하는 대규모 조직의 React 시스템|Turborepo 및 Nx와 같은 빌드 오케스트레이션 도구를 활용하는 대규모 조직의 React 시스템]]
- **Contradictions/Notes:** 소스에 따르면 [[Atomic Design|Atomic Design]]은 UI 컴포넌트와 디자인 시스템을 구성하는 데는 강력한 언어지만 도메인 로직의 위치를 일관되게 지정하기 어렵게 만드는 반면, FSD는 명확한 기능(Feature) 경계와 의존성 방향을 제공하여 대규모 애플리케이션의 아키텍처적 일관성을 유지하는 데 더 적합하다고 비교됩니다 [4].
---
*Last updated: 2026-04-26*
@@ -1,28 +0,0 @@
# [[Feature-Sliced Design|Feature-Sliced Design]]
## 📌 Brief Summary
Feature-Sliced Design(FSD)은 조직 전반의 일관성을 보장하기 위해 애플리케이션 및 패키지 내의 코드를 구성하는 커뮤니티 주도의 프론트엔드 아키텍처 방법론입니다 [1, 2]. 이 방법론은 명확한 책임과 의존성 방향을 가진 여러 계층(layer)으로 코드베이스를 나누어, 예측 가능한 슬라이스(slice) 경계와 명시적인 공개 API(Public API)를 제공합니다 [1-3]. 이를 통해 '글로벌 공유 폴더(global shared folder)'가 무분별한 코드의 쓰레기장으로 변하는 것을 방지하고, 유지보수가 용이한 확장 가능한 프론트엔드 시스템을 구축할 수 있습니다 [4, 5].
## 📖 Core Content
* **계층화된 아키텍처 (Layered [[Architecture|Architecture]]):** FSD는 명확한 책임을 가진 여러 계층으로 코드를 분리합니다 [1].
* *Shared:* 가장 하위 계층으로 일반적인 UI 컴포넌트(원자), 헬퍼 함수, 디자인 토큰을 포함하며, 다른 어떤 계층에서도 가져올(import) 수 없습니다 [1, 6].
* *Entities:* 핵심 비즈니스 도메인(예: 사용자, 제품, 주문)을 나타내며 데이터 구조와 도메인별 로직 및 UI/상태 표현을 포함합니다 [1, 6].
* *Features:* 사용자에게 가치를 제공하는 비즈니스 로직(예: 장바구니 추가, 결제 진행)을 포함합니다 [1, 6].
* *Widgets:* 기능(features)과 엔티티(entities)를 결합한 상위 수준의 UI 블록(예: 제품 카드, 네비게이션 헤더)입니다 [1].
* *Pages:* 위젯과 기능을 기반으로 구축된 전체 페이지 구성입니다 [1].
* *App:* 글로벌 프로바이더, 스타일, 라우팅이 초기화되는 최상위 진입점입니다 [1].
* **엄격한 의존성 방향 및 경계 규칙:** 우발적인 결합(coupling)을 줄이기 위해 강력한 제약 조건을 강제합니다 [3].
* 앱(App)은 패키지의 깊은 내부 파일이 아닌 오직 공개 API에서만 임포트해야 합니다 [3, 7].
* 의도적으로 공유된 슬라이스가 없는 한, 특정 기능(Feature)은 다른 기능(Feature)을 직접 가져올(import) 수 없습니다 [7].
* Shared 패키지는 비즈니스 흐름을 포함하지 않고 오직 재사용 가능한 기본 요소로만 작게 유지되어야 합니다 [7].
* **도메인 주도 설계(DDD)와의 조화:** 기존 DDD의 추상적인 개념을 실용적인 파일 시스템 구조로 구체화하여, 임포트(import) 경로와 디렉토리 구조만으로도 도메인 경계를 명확히 식별할 수 있게 돕습니다 [6].
## 🔗 Knowledge Connections
- **Related Topics:** [[Monorepo Architecture|Monorepo Architecture]], Atomic Design, Domain-Driven Design (DDD), [[Component Library Architecture|Component Library Architecture]], Public API
- **Projects/Contexts:** 대규모 프론트엔드 애플리케이션 및 디자인 시스템 구축, [[Turborepo|Turborepo]] 또는 Nx를 활용한 확장 가능한 프론트엔드 모노레포 관리 환경 [5, 8, 9].
- **Contradictions/Notes:** 소스에 따르면 FSD는 [[Atomic Design|Atomic Design]]과 경쟁하기보다는 상호 보완적으로 사용될 수 있습니다. UI 라이브러리에는 [[Atomic Design|Atomic Design]]을 사용하여 "원자(Atoms)"를 순수하게 유지하고, 애플리케이션의 비즈니스 로직은 FSD의 Feature 기반 구조를 따르도록 결합하는 방식이 성공적인 아키텍처 패턴으로 제시됩니다 [10].
---
*Last updated: 2026-04-26*
@@ -1,24 +0,0 @@
# [[Fiber Architecture|Fiber Architecture]]
## 📌 Brief Summary
React 16에서 도입된 Fiber [[Architecture|Architecture]]는 동시성 렌더링(Concurrent Rendering)을 지원하기 위해 근본적으로 재작성된 React의 재조정(Reconciliation) 엔진입니다 [1-3]. 기존의 동기식 렌더링이 메인 스레드를 차단하여 UI가 멈추던 문제를 해결하고자, 렌더링 작업을 '파이버(Fiber)'라는 작은 단위의 노드로 쪼개어 점진적으로 처리합니다 [4, 5]. 이를 통해 React는 렌더링을 일시 중지하거나 브라우저에 제어권을 양보하고, 우선순위가 높은 작업을 먼저 처리한 후 다시 렌더링을 재개하는 타임 슬라이싱([[Time-Slicing|Time-Slicing]]) 스케줄링을 구현할 수 있게 되었습니다 [4-6].
## 📖 Core Content
* **동기식 차단(Synchronous [[Blocking|Blocking]])의 한계 극복:**
Fiber 도입 이전의 React는 '스택 재조정자(Stack Reconciler)'를 사용하여 전체 컴포넌트 트리를 단일 재귀 호출로 동기 처리했습니다 [4]. 이 방식은 대규모 애플리케이션에서 브라우저의 프레임 예산(16.6ms)을 초과할 경우 메인 스레드를 차단하여 사용자 입력이나 애니메이션을 지연시켰습니다 [4]. Fiber는 작업을 작은 단위로 나누어 브라우저가 높은 우선순위의 작업을 가로채 처리할 수 있게 함으로써 이 문제를 해결합니다 [4, 5, 7].
* **작업 루프(Work Loop)와 두 가지 렌더링 단계:**
Fiber의 재조정 과정은 작업 중단과 우선순위 관리를 위해 두 가지 명확한 단계로 나뉩니다 [8].
* **렌더링 단계 (Render Phase):** 이 단계는 비동기적이며 중단할 수 있습니다 [8]. 실제 DOM을 변경하지 않고 메모리 상의 파이버 트리를 순회하면서 이전 상태와 새로운 상태의 차이를 계산하고, 변경이 필요한 파이버들의 목록(Effect list)을 구성합니다 [8, 9]. 더 높은 우선순위 작업이 들어오면 일시 중단, 폐기 또는 재시작될 수 있으므로, 이 단계에서는 사이드 이펙트가 발생해서는 안 됩니다 [8-10].
* **커밋 단계 (Commit Phase):** 이 단계는 동기적이며 중단할 수 없습니다 [11]. 렌더링 단계에서 만들어진 변경 사항(삽입, 삭제, 업데이트)을 한 번에 실제 DOM에 적용합니다 [9, 11, 12]. 이 시점에 실제 DOM이 변형되며 각종 생명주기 메서드나 레이아웃 이펙트(`useLayoutEffect`)가 실행됩니다 [11, 12].
* **레인(Lane) 모델을 통한 우선순위 스케줄링:**
Fiber는 32비트 정수 비트마스크 시스템인 '레인(Lane)'을 사용하여 작업의 우선순위를 정밀하게 관리합니다 [13, 14]. 클릭이나 타이핑 등 즉각적 반응이 필요한 작업(Sync Lane), 스크롤링(InputContinuous Lane), 일반적인 상태 업데이트(Default Lane), 백그라운드 작업(Idle Lane)으로 업데이트를 분류합니다 [6, 15]. 이를 통해 사용자 상호작용과 같은 '긴급한' 업데이트가 데이터 렌더링 같은 '비긴급' UI 전환보다 먼저 처리되도록 보장합니다 [6, 16].
* **작업 진행 상태(WIP) 트리 관리:**
React는 현재 화면에 그려진 상태를 추적할 뿐만 아니라 작업 중인 상태를 나타내는 WIP(Work-in-progress) 트리를 별도로 관리합니다 [10]. 스케줄러의 우선순위에 따라 메인 스레드가 바쁘면 이 WIP 트리의 작업을 일시 중지하고, 브라우저가 유휴 상태일 때 다시 재개할 수 있습니다 [10].
## 🔗 Knowledge Connections
- **Related Topics:** [[Virtual DOM|Virtual DOM]], Reconciliation, Concurrent Rendering, [[Critical Rendering Path|Critical Rendering Path]]
- **Projects/Contexts:** [[React 16+ Core Engine|React 16+ Core Engine]], [[브라우저 메인 스레드 최적화 및 타임 슬라이싱|브라우저 메인 스레드 최적화 및 타임 슬라이싱]]
- **Contradictions/Notes:** Fiber의 동시성 렌더링 기능(예: `[[useTransition|useTransition]]`, `[[useDeferredValue|useDeferredValue]]`)은 코드의 물리적인 실행 속도를 높이는 것은 아닙니다 [17]. 무거운 연산으로 인한 병목이 즉각적인 사용자 상호작용을 방해하지 않도록 뒤로 미룸(Deferring)으로써, 체감 성능(Perceived Performance) 측면에서 애플리케이션이 훨씬 "더 빠르게 느껴지도록" 만드는 것이 핵심입니다 [17].
---
*Last updated: 2026-04-25*
@@ -1,25 +0,0 @@
# [[Fiber 아키텍처 (Fiber Architecture)|Fiber 아키텍처 (Fiber Architecture]]
## 📌Brief 신Summary
Fiber 아키텍처는 동시성 렌더링([[Concurrent Rendering|Concurrent Rendering]])을 지원하고 렌더링 프로세스를 세밀하게 제어하기 위해 React 16에서 도입된 재조정(Reconciliation) 엔진의 완전한 재작성 버전이다 [1-3]. 이 아키텍처는 렌더링 작업을 '파이버 노드(Fiber node)'라고 불리는 작은 작업 단위(unit of work)로 분할하여 점진적으로 처리하는 작업 루프(work loop)를 기반으로 작동한다 [4, 5]. 렌더링 도중 우선순위가 높은 상호작용이 발생하면 작업을 일시 중지하고 브라우저에 제어권을 넘겼다가 다시 시작할 수 있는 '타임 슬라이싱([[Time-Slicing|Time-Slicing]])'을 가능하게 하여 UI의 반응성을 크게 향상시킨다 [4, 5].
## 📖 Core Content
* **작업 루프와 파이버 트리 (Work Loop and Fiber Tree):**
이전의 React는 스택 재조정자(stack reconciler)를 사용하여 전체 컴포넌트 트리를 단일 재귀 호출로 한 번에 처리했기 때문에 메인 스레드를 차단하는 문제가 있었다 [4]. Fiber는 컴포넌트 트리의 각 노드를 자식(child), 형제(sibling), 부모(return)에 대한 포인터를 가진 '파이버 노드'로 구성하며, 이를 단위로 작업 루프를 돈다 [6, 7]. 스케줄러는 트리를 깊이 우선 탐색(depth-first) 방식으로 순회하며 렌더링 작업을 수행하고, 현재 프레임에 남은 시간이 없으면 작업을 일시 중단(yield)하여 브라우저의 끊김을 방지한다 [7, 8].
* **재조정 단계 (Reconciliation Phases):**
React의 재조정 프로세스는 작업 중단 및 우선순위 지정을 가능하게 하기 위해 두 가지 명확한 단계로 나뉜다 [9].
* **렌더 단계 (Render phase):** 트리를 순회하며 이전 상태와 새로운 상태 간의 차이를 계산하는 단계로, DOM을 직접 수정하지 않는다 [9, 10]. 이 단계는 언제든 중단, 취소, 재시작이 가능하며 부작용(side effects)을 실행해서는 안 된다 [9, 10]. 렌더 단계가 끝나면 변경이 필요한 파이버들만 모아 이펙트 목록(effect list)을 구성한다 [11].
* **커밋 단계 (Commit phase):** 중단될 수 없는 동기적인 단계로, 렌더 단계에서 생성된 이펙트 목록을 바탕으로 DOM 노드의 삽입, 삭제, 업데이트를 한 번에 적용한다 [10, 12]. 이 단계에서 `useLayoutEffect``useEffect`와 같은 생명주기 메서드와 훅이 실행된다 [10, 12, 13].
* **우선순위 스케줄링과 레인 모델 (Priority and [[Lane Model|Lane Model]]):**
Fiber는 여러 업데이트의 혼합된 우선순위를 효율적으로 관리하기 위해 '레인(Lanes)'이라는 비트마스크 시스템을 사용한다 [14, 15]. 작업은 사용자 타이핑이나 클릭처럼 즉각적인 처리가 필요한 동기(Sync) 레인부터 스크롤과 같은 사용자 차단(User-[[Blocking|Blocking]]) 레인, 데이터 페칭 결과를 나타내는 기본(Default) 레인, 백그라운드 작업인 유휴(Idle) 레인 등으로 분류된다 [14, 16]. 이를 통해 긴급한 UI 상호작용이 무거운 비동기 업데이트보다 먼저 처리될 수 있다 [14, 17].
* **동시성 기능의 기반 (Foundation for Concurrent Features):**
이러한 중단 가능한 렌더링 및 우선순위 관리 구조 덕분에 React는 `[[useTransition|useTransition]]``[[useDeferredValue|useDeferredValue]]`와 같은 동시성 훅(concurrent hooks)을 도입할 수 있게 되었다 [18]. 이 훅들은 무거운 연산이 진행되는 동안에도 긴급한 사용자 입력을 위해 메인 스레드를 확보하여 부드러운 앱 경험을 유지하게 돕는다 [18, 19].
## 🔗 Knowledge Connections
- **Related Topics:** [[가상 DOM (Virtual DOM)|가상 DOM (Virtual DOM]], 재조정 (Reconciliation), [[동시성 렌더링 (Concurrent Rendering)|동시성 렌더링 (Concurrent Rendering]], 타임 슬라이싱 (Time-Slicing)
- **Projects/Contexts:** React 16, [[React 19|React 19]] 동시성 훅 (useTransition, useDeferredValue)
- **Contradictions/Notes:** 소스 간의 의견 충돌은 없으며, Fiber 아키텍처의 목표는 복잡한 렌더링 작업으로 인해 프레임이 떨어지는 기존의 스택 재조정자(Stack Reconciler) 문제를 해결하기 위해 필수적으로 도입된 구조적 변화라고 일관되게 설명된다 [2, 4].
---
*Last updated: 2026-04-25*
@@ -1,35 +0,0 @@
# [[Fiber 아키텍처와 동시성 (Concurrent Rendering)|Fiber 아키텍처와 동시성 (Concurrent Rendering]]
## 📌 Brief Summary
React의 **Fiber 아키텍처**는 단일 호출로 전체 트리를 동기적으로 렌더링하여 메인 스레드를 차단하던 기존의 한계를 극복하기 위해 재작성된 재조정([[Reconciliation|Reconciliation]]) 엔진입니다 [1, 2]. 이 엔진은 렌더링 과정을 작은 '작은 작업 단위(Unit of work)'로 분할하여 **동시성 렌더링(Concurrent Rendering)**을 구현합니다 [2, 3]. 결과적으로 긴급한 사용자 상호작용(예: 클릭, 타이핑)이 무거운 렌더링 작업에 의해 지연되지 않도록 작업을 일시 중지, 재개, 우선순위 재조정하여 사용자 인터페이스(UI)의 반응성을 극대화합니다 [4, 5].
## 📖 Core Content
- **기존 렌더링의 문제점과 Fiber의 도입:**
React 16 이전에는 전체 컴포넌트 트리를 단일 재귀 호출로 처리하는 '스택 재조정자(Stack Reconciler)'를 사용했습니다 [2]. 이 방식은 렌더링이 완료될 때까지 메인 스레드를 차단(synchronous [[Blocking|Blocking]])하여, 큰 규모의 애플리케이션에서는 UI가 사용자의 입력이나 애니메이션에 반응하지 못하는 문제를 발생시켰습니다 [2]. 이를 해결하기 위해 렌더링을 중단 및 재개할 수 있는 Fiber 아키텍처가 도입되었습니다 [1, 2].
- **작업 루프(Work Loop)와 작업 단위(Unit of Work):**
Fiber는 컴포넌트나 DOM 요소를 나타내는 'Fiber 노드' 단위로 렌더링 작업을 수행합니다 [2, 3]. 렌더링을 여러 프레임에 분산시키기 위해 '작업 루프'를 작동하며, 다음 작업을 선택하여 처리(beginWork)하다가 우선순위가 높은 작업이 발생하면 렌더링을 일시 중단하고 브라우저에 제어권을 양보(Yield)합니다 [3, 5].
- **재조정(Reconciliation) 단계의 분리:**
동시성 렌더링을 위해 React의 재조정 과정은 중단 가능성에 따라 두 가지 단계로 나뉩니다 [6].
* **렌더링 단계(Render Phase):** 컴포넌트 트리를 순회하며 이전 상태와 새로운 상태의 차이를 계산하고 효과 목록(Effect list)을 구축합니다 [6]. 이 단계는 실제 DOM을 변경하지 않는 순수한 연산 과정이므로 **언제든지 일시 중지, 취소 또는 재시작이 가능**합니다 [6, 7].
* **커밋 단계(Commit Phase):** 렌더링 단계에서 만들어진 변경 사항(효과 목록)을 실제 DOM에 한 번에 적용합니다 [8]. 이 과정은 **동기적이고 중단할 수 없습니다** [7, 8].
- **우선순위 제어 및 차선 모델([[Lane Model|Lane Model]]):**
React는 타임 슬라이싱([[Time-Slicing|Time-Slicing]])과 동시성을 효과적으로 관리하기 위해 32비트 정수 기반의 '차선(Lanes)' 시스템을 활용합니다 [4, 9].
* 동기적 차선(Sync Lane): 타이핑, 클릭 등 즉시 처리해야 하는 긴급한 작업 [4, 10].
* 입력 연속 차선(InputContinuous Lane): 스크롤, 마우스 호버 등 유동적인 움직임 [4, 10].
* 그 외에도 데이터 페칭 결과를 처리하는 기본 차선(Default Lane)과 백그라운드 렌더링을 처리하는 유휴 차선(Idle Lane)으로 나뉩니다 [4].
이러한 세밀한 모델 덕분에 작업 중인 Fiber(WIP Fibers)를 우선순위에 따라 지연시키거나 우선 처리할 수 있습니다 [11].
- **동시성 기능(Concurrent Features)의 활용:**
Fiber의 동시성 렌더링 구조는 [[React 18|React 18]], 19의 `useTransition``[[useDeferredValue|useDeferredValue]]`와 같은 훅(Hook)을 가능하게 합니다 [12, 13]. 긴급하지 않은 업데이트의 우선순위를 낮춰 처리함으로써 무거운 리스트 필터링이나 데이터 계산 중에도 앱의 반응성을 부드럽게 유지할 수 있습니다 [12, 14].
## 🔗 Knowledge Connections
- **Related Topics:** [[가상 DOM과 재조정 (Virtual DOM and Reconciliation)|가상 DOM과 재조정 (Virtual DOM and Reconciliation]], 차선 모델과 작업 우선순위 (Lane Model & Priorities), Time-Slicing, [[React 동시성 훅 (useTransition, useDeferredValue)|React 동시성 훅 (useTransition, useDeferredValue]]
- **Projects/Contexts:** [[메인 스레드 차단 문제 해결을 위한 React 16의 Fiber 엔진 교체 및 React 18, 19의 동시성 렌더링 적용 사례|메인 스레드 차단 문제 해결을 위한 React 16의 Fiber 엔진 교체 및 React 18, 19의 동시성 렌더링 적용 사례]]
- **Contradictions/Notes:** 소스 전반에 걸쳐 내용이 일치하며 상충되는 의견은 없습니다. 모든 소스는 Fiber 아키텍처가 렌더링을 작은 단계로 분할하고 우선순위를 부여함으로써 메인 스레드의 부하를 줄여 동시성과 반응성을 달성한다는 점을 일관되게 강조합니다.
---
*Last updated: 2026-04-25*
@@ -1,17 +0,0 @@
# [[Figma Design System Integration|Figma DesignSystem Integration]]
## 📌 Brief Summary
[[Figma|Figma]] Design System Integration(Figma 디자인 시스템 통합)은 Figma에서 결정된 디자인 요소(색상, 글꼴, 간격 등)를 애플리케이션의 실제 코드베이스와 원활하게 동기화하는 프로세스를 의미합니다 [1]. 주로 Tokens Studio for Figma와 같은 플러그인을 통해 디자인 결정을 JSON 형태의 디자인 토큰으로 구조화한 후, [[Style Dictionary|Style Dictionary]] 등의 도구로 React용 CSS 변수나 코드로 자동 변환합니다 [2], [3]. 최근에는 AI 에이전트나 코드 기반 UI 도구를 활용해 컴포넌트 스펙 생성과 디자이너-개발자 간 핸드오프를 자동화하여, 대규모 프론트엔드 아키텍처 내에서 디자인 시스템을 일관되고 확장 가능하게 유지하는 핵심 기술로 자리 잡고 있습니다 [4], [5], [6].
## 📖 Core Content
- **디자인 토큰 기반의 자동화 파이프라인:** 디자인 시스템 구축 시 Figma를 단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]])으로 설정하여 스타일링 결정을 중앙화합니다 [1], [7]. Figma에서 내보낸 다크/라이트 모드 등의 JSON 토큰 데이터를 Style Dictionary를 사용해 처리하면, 플랫폼에 종속되지 않은 토큰이 React 애플리케이션에서 즉시 사용할 수 있는 JavaScript/TypeScript 객체 또는 CSS 변수 형태로 생성됩니다 [3], [8]. 이 자동화 파이프라인은 수동으로 스타일을 복제할 때 발생하는 오류를 방지하고, 일관성 있는 동적 테마([[Dynamic Theming|Dynamic Theming]]) 적용을 가능하게 합니다 [3], [7].
- **코드 기반 컴포넌트 직접 연동:** 디자인 도구와 실제 코드 간의 불일치를 해결하기 위해 UXPin 등은 사용자 지정 Git React 컴포넌트 저장소를 디자인 워크플로우에 직접 통합하는 방식을 제공합니다 [5], [6]. 이를 통해 디자이너는 코드로 렌더링된 실제 컴포넌트를 이용해 프로토타입을 제작하게 되며, 코드베이스와 디자인 토큰이 자동으로 동기화됩니다 [6]. 반면, 이러한 코드 기반 통합이 불가능한 기존 디자인 툴 환경에서는 수동 JSON 내보내기와 빌드 파이프라인을 거쳐야 하므로 디자인과 개발 환경의 괴리(Drift)를 막기 위한 엄격한 관리 프로세스가 필요합니다 [9].
- **AI 에이전트 및 MCP를 활용한 컴포넌트 스펙 자동화:** 대규모 UI 시스템에서 문서화의 병목을 해결하기 위해 Uber는 Figma Console MCP(Model Context Protocol)와 Cursor 내 AI 에이전트를 활용한 'uSpec' 시스템을 구축했습니다 [10], [4]. 이 AI 에이전트는 로컬 웹소켓을 통해 Figma 파일에 직접 연결한 후, 컴포넌트 트리, 토큰 값, 변형(Variants) 구조를 크롤링합니다 [11], [12]. 분석된 데이터를 기반으로 접근성 규칙(VoiceOver, ARIA 등)과 구조 스펙이 담긴 문서를 단 몇 분 만에 Figma 파일 내에 직접 렌더링하여 엔터프라이즈급 확장성을 입증했습니다 [13], [14], [15], [16].
## 🔗 Knowledge Connections
- **Related Topics:** [[Design Tokens|Design Tokens]], Dynamic Theming, [[Component-Based Design|Component-Based Design]], Automated Token Distribution
- **Projects/Contexts:** Uber's Base Design System / uSpec, Tokens Studio for Figma, [[Style Dictionary|Style Dictionary]], [[UXPin Merge|UXPin Merge]]
- **Contradictions/Notes:** Figma에서 토큰을 수동으로 내보내고 동기화하는 방식은 유용하지만 설계와 개발 코드 간의 드리프트(Drift)를 유발할 수 있습니다 [9]. 따라서 대규모 조직에서는 CI/CD 파이프라인을 통해 토큰 릴리스를 자동화하고 코드 리뷰와 동일한 수준의 엄격한 거버넌스를 갖추는 것이 필수적입니다 [17], [18], [19].
---
*Last updated: 2026-04-26*
@@ -1,18 +0,0 @@
# [[Figma Integration|Figma Integration]]
## 📌 Brief Summary
[[Figma|Figma]] Integration(피그마 통합)은 현대적인 React 프론트엔드 아키텍처에서 디자인 결정 사항을 코드와 동기화하고 자동화하는 핵심 프로세스입니다 [1, 2]. 주로 Figma에서 색상, 폰트, 간격 등의 디자인 토큰을 JSON 형식으로 추출하여 개발 환경에 적용하는 방식을 의미합니다 [2]. 더 나아가, AI 에이전트와 전용 프로토콜을 활용하여 Figma 파일 내에서 컴포넌트 명세서를 자동으로 생성하는 등 디자인과 개발 간의 간극을 줄이고 확장성 있는 UI 시스템을 구축하는 데 필수적으로 사용됩니다 [3, 4].
## 📖 Core Content
* **디자인 토큰 추출 및 변환:** Figma는 확장 가능한 디자인 시스템의 단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]]) 역할을 합니다 [1, 5]. Tokens Studio for Figma와 같은 플러그인을 사용하면 디자이너가 설정한 디자인 결정을 JSON 구조로 추출할 수 있습니다 [2, 6]. 이렇게 내보낸 JSON 파일은 Style Dictionary와 같은 도구를 거쳐 React 애플리케이션에서 직접 사용할 수 있는 CSS 변수나 [[JavaScript|JavaScript]]/TypeScript 테마 객체로 자동 변환됩니다 [7, 8].
* **파이프라인 동기화:** Figma를 개발 툴 체인 파이프라인과 직접 연결하면 디자인 시스템의 일관성을 유지할 수 있습니다 [9]. 디자인 토큰을 수동으로 동기화하거나 공유 저장소에 저장하는 방식을 넘어, Superflex.ai와 같은 자동화 플랫폼을 활용해 Figma의 디자인 시스템 변경 사항을 React 코드로 즉시 동기화하고 생성할 수 있습니다 [6, 10].
* **AI 기반 컴포넌트 명세([[Specification|Specification]]) 자동화:** Uber의 사례처럼, 대규모 컴포넌트 라이브러리 관리를 위해 AI와 Figma를 통합하는 고도화된 방식도 존재합니다 [3]. Uber는 오픈 소스인 'Figma Console MCP(Model Context Protocol)'를 통해 Cursor의 AI 에이전트를 Figma 데스크톱에 로컬로 직접 연결하는 'uSpec' 시스템을 구축했습니다 [4, 11].
* **명세서 렌더링:** 이 통합 시스템은 AI가 Figma 파일의 컴포넌트 트리, 하위 컴포넌트 구조, 디자인 토큰 및 변수를 크롤링하여 API, 색상 주석, 화면 판독기(Screen reader) 접근성 속성 등을 파악하게 합니다 [11-13]. 이후 AI가 완성된 디자인 설계 명세서를 Figma 파일 내에 직접 렌더링함으로써, 수동으로 몇 주가 걸리던 문서화 작업을 단 몇 분으로 단축시킵니다 [3, 14].
## 🔗 Knowledge Connections
- **Related Topics:** [[Design Tokens|Design Tokens]], Style Dictionary, [[Dynamic Theming|Dynamic Theming]]
- **Projects/Contexts:** Uber Base DesignSystem, Figma Console MCP, Tokens Studio for Figma
- **Contradictions/Notes:** 소스 내에서 Figma 통합에 대한 모순된 주장은 발견되지 않으며, 모든 소스가 공통적으로 Figma를 단일 진실 공급원(Source of Truth)으로 삼아 코드 및 문서화를 자동 동기화하는 파이프라인 구축을 권장합니다 [3, 5, 15].
---
*Last updated: 2026-04-26*

Some files were not shown because too many files have changed in this diff Show More