c24165b8bc
에이전트 8종(대화형/프로그래머 C·S/디자이너/설계자/기획자/QA/PD/PM)에게 [공통 기본 능력 + 롤별 Specialty] 2층으로 지식을 주입하기 위한 재분류. 문서 내용·포맷은 무수정, 폴더 이동만 (6,372개 문서 수 보존 확인). - Topic_Programming → Domain_Programming (내부 구조 보존) - Topic_Graphic → Domain_Design - Topic_Business → Domain_Product - Topic_General → Domain_General - _Common 신설: Math(구 Topic_Math_Specialty), Reasoning(구 General/From_Thinking & Reasoning), Reasoning_Creativity(구 General/From_창의성), Communication(Poetic_Blog_Writing + From_writing) - 타 도메인의 From_* 폴더는 유지 (출처 표기일 뿐, 이미 도메인에 맞게 분류된 문서) - 빈 폴더 정리 (memory/procedures) - 에이전트→폴더 매핑은 workspace의 .astra/agent-knowledge-map.json (9개 에이전트) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6.8 KiB
6.8 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-반응형-윈도우-리사이즈-resize-이벤트-처리 | 반응형 윈도우 리사이즈(Resize) 이벤트 처리 | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
반응형 윈도우 리사이즈(Resize) 이벤트 처리
매 한 줄
"매 resize 의 fire 매 cheap 매 listener 매 expensive — debounce 또는 ResizeObserver". window resize 매 60fps+ 의 fire — 매 naive listener 매 layout thrash. 매 modern (2026) 의 ResizeObserver 의 element-level + native browser-throttled API.
매 핵심
매 두 종류 의 API
window.addEventListener('resize', ...)— viewport-level, fires 매 every pixel change.ResizeObserver— element-level, browser-throttled, observes contentBox/borderBox.
매 throttle vs debounce
- Debounce — fire only N ms 후 last event (e.g., resize stops).
- Throttle — fire at most every N ms (continuous fire).
- Resize: 보통 debounce (final size 만 needed) 또는 throttle (live preview).
매 응용
- Responsive breakpoint — JS-driven layout.
- Canvas/Chart resize — re-draw on size change.
- Virtualized list — recalculate row count.
- Modal positioning — re-center.
💻 패턴
1. ResizeObserver (modern, preferred)
const ro = new ResizeObserver((entries) => {
for (const entry of entries) {
const { width, height } = entry.contentRect;
console.log('resized:', width, height);
}
});
const el = document.querySelector('.box')!;
ro.observe(el);
// cleanup
// ro.unobserve(el); ro.disconnect();
2. React hook: useResizeObserver
import { useEffect, useState, useRef } from 'react';
export function useResizeObserver<T extends HTMLElement>() {
const ref = useRef<T>(null);
const [size, setSize] = useState({ width: 0, height: 0 });
useEffect(() => {
if (!ref.current) return;
const ro = new ResizeObserver(([entry]) => {
const { width, height } = entry.contentRect;
setSize({ width, height });
});
ro.observe(ref.current);
return () => ro.disconnect();
}, []);
return [ref, size] as const;
}
// usage
function Card() {
const [ref, { width }] = useResizeObserver<HTMLDivElement>();
return <div ref={ref}>{width < 400 ? <Compact /> : <Full />}</div>;
}
3. Window resize with debounce
function debounce<T extends (...args: any[]) => any>(fn: T, ms = 200): T {
let timer: ReturnType<typeof setTimeout> | null = null;
return ((...args: Parameters<T>) => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => fn(...args), ms);
}) as T;
}
const onResize = debounce(() => {
console.log('done resizing:', window.innerWidth);
}, 200);
window.addEventListener('resize', onResize);
4. React useWindowSize hook
import { useEffect, useState } from 'react';
export function useWindowSize() {
const [size, setSize] = useState({
width: typeof window === 'undefined' ? 0 : window.innerWidth,
height: typeof window === 'undefined' ? 0 : window.innerHeight,
});
useEffect(() => {
let raf = 0;
const onResize = () => {
cancelAnimationFrame(raf);
raf = requestAnimationFrame(() => {
setSize({ width: window.innerWidth, height: window.innerHeight });
});
};
window.addEventListener('resize', onResize, { passive: true });
return () => {
window.removeEventListener('resize', onResize);
cancelAnimationFrame(raf);
};
}, []);
return size;
}
5. Throttle with rAF
function rafThrottle<T extends (...args: any[]) => any>(fn: T): T {
let raf = 0;
let lastArgs: Parameters<T>;
return ((...args: Parameters<T>) => {
lastArgs = args;
if (raf) return;
raf = requestAnimationFrame(() => {
fn(...lastArgs);
raf = 0;
});
}) as T;
}
window.addEventListener('resize', rafThrottle(() => {
// runs at most once per frame
redrawCanvas();
}));
6. matchMedia (breakpoint detection)
const mql = window.matchMedia('(min-width: 768px)');
function onChange(e: MediaQueryListEvent) {
console.log('is desktop:', e.matches);
}
mql.addEventListener('change', onChange);
console.log('initial desktop:', mql.matches);
7. Canvas resize (HiDPI handling)
function fitCanvasToDPR(canvas: HTMLCanvasElement) {
const dpr = window.devicePixelRatio || 1;
const rect = canvas.getBoundingClientRect();
canvas.width = rect.width * dpr;
canvas.height = rect.height * dpr;
const ctx = canvas.getContext('2d')!;
ctx.scale(dpr, dpr);
return ctx;
}
const ro = new ResizeObserver(([entry]) => {
const canvas = entry.target as HTMLCanvasElement;
fitCanvasToDPR(canvas);
draw(canvas.getContext('2d')!);
});
ro.observe(canvas);
매 결정 기준
| 상황 | Approach |
|---|---|
| Element-level size watch | ResizeObserver (browser-throttled, no manual debounce). |
| Window-level (viewport) | window.addEventListener('resize') + debounce. |
| Smooth visual feedback during drag | requestAnimationFrame throttle. |
| Breakpoint change only | matchMedia (fires on threshold cross only). |
| Canvas / chart redraw | ResizeObserver + DPR scaling. |
기본값: ResizeObserver 의 element-level. matchMedia 의 breakpoint. window resize 의 only viewport-wide concerns + debounce 200ms.
🔗 Graph
- 변형: ResizeObserver · IntersectionObserver
- 응용: 가상 스크롤
- Adjacent: debounce / throttle · requestAnimationFrame · 컨테이너 쿼리 (Container Queries)
🤖 LLM 활용
언제: dynamic layout, canvas/chart, virtualized lists, modal repositioning, JS-driven breakpoint. 언제 X: pure CSS responsive 매 sufficient — JS resize handler 매 unneeded.
❌ 안티패턴
- No debounce/throttle on window.resize: 60+ fires/sec 매 layout thrash.
offsetWidthin resize handler without rAF: forced sync layout.- Forgetting cleanup: memory leak (especially in React without
removeEventListener). - Polling
window.innerWidth: use event-driven approach. - Heavy work synchronously: canvas full redraw 매 each event — defer/batch.
🧪 검증 / 중복
- Verified (MDN ResizeObserver 2026, web.dev resize patterns, React hooks docs).
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — full content with ResizeObserver/debounce/rAF/matchMedia patterns |