2026-01-06
클로저란?
정의
- 함수가 선언될 때의 스코프를 기억하여, 함수가 생성된 이후에도 그 스코프에 접근할 수 있는 기능
- 함수가 선언될 당시의 렉시컬 스코프를 기억해서, 함수 외부의 변수를 함수 실행 이후에도 접근할 수 있게 해주는 자바스크립트의 특성
기본예제
function outer() {
let count = 0;
return function inner() {
count++;
return count;
};
}
const counter = outer();
counter(); // 1
counter(); // 2
- outer는 실행이 끝났지만
- inner가 count를 참조하고 있어서
- count는 계속 살아 있다 → 클로저
클로저의 활용
- 데이터 은닉에 활용됨 (상태은닉, 캡슐화)
function createCounter() { let count = 0; return { increase() { count++; }, getCount() { return count; } }; } const counter = createCounter(); counter.increase(); counter.getCount(); // 1상태를 외부에서 직접 수정하지 못하게 보호 가능 (전역 변수 없이 상태를 유지)
- 비동기 작업에 활용됨 (이벤트 핸들러에서 상태 유지)
function attachHandler() { let clicked = false; button.addEventListener('click', () => { if (!clicked) { console.log('처음 클릭'); clicked = true; } }); }- 이벤트가 나중에 실행돼도
- 선언 당시의 clicked 상태를 기억한다
동작원리
자바스크립트는 함수가 선언될 때 스코프가 결정되는 렉시컬 스코프 언어다. 내부 함수가 외부 함수의 변수를 참조하고 있으면, 외부 함수 실행이 끝난 뒤에도 그 변수는 가비지 컬렉션되지 않고 메모리에 유지된다. 이 상태를 클로저라고 부른다.
React와의 연결
React의 함수 컴포넌트와 useState, useEffect도 클로저 기반으로 동작한다.
const [count, setCount] = useState(0);
- 컴포넌트 함수가 다시 실행돼도
- 이전 상태를 기억하는 이유 → 클로저
useEffect(() => { setInterval(() => { console.log(count); }, 1000); }, []); - count는 초기값만 기억
- 클로저가 생성된 시점의 값이 고정됨
- 아래를 이용해 해결
setCount(prev => prev + 1);
특히 useEffect에서 이전 상태를 참조하는 문제(stale closure)는 클로저 이해가 없으면 디버깅이 어렵다.
단점
- 클로저는 메모리를 계속 참조하므로
- 이벤트 제거, 타이머 정리 등을 하지 않으면 메모리 누수 위험이 있다
요약
클로저는 상태를 은닉하거나 비동기 환경에서 실행 맥락을 유지할 때 많이 활용된다. 특히 이벤트 핸들러나 React 훅처럼 함수가 나중에 실행되는 환경에서, 선언 당시의 값을 기억해야 할 때 핵심적인 역할을 한다.
참고자료
reflow와 repaint의 차이점
우선 알아야 할 것
브라우저 렌더링 과정
1. HTML 파싱 → DOM 생성
2. CSS 파싱 → CSSOM 생성
3. DOM + CSSOM → Render Tree
4. Layout (Reflow) ← 위치·크기 계산
5. Paint (Repaint) ← 색상, 그림자, 테두리 등 그리기
6. Composite
reflow란?
요소의 위치, 크기, 정렬이 바뀌어서 레이아웃을 다시 계산하는 과정
발생조건
- width / height 변경
- margin / padding 변경
- position 변경
- display 변경
- font-size 변경
- DOM 요소 추가/삭제
- 창 크기 변경 (resize)
특징
- 상위 → 하위, 또는 전체 레이아웃에 연쇄 영향
- 성능 비용이 매우 큼
- Reflow가 발생하면 Repaint는 거의 항상 따라온다
Repaint란?
레이아웃은 그대로 두고, 시각적 스타일만 다시 그리는 과정
발생조건
- color 변경
- background-color 변경
- visibility 변경
- box-shadow 변경
특징
- 위치·크기 계산 없음
- Reflow보다 비용이 적음
차이점 정리
| 구분 | Reflow | Repaint |
|---|---|---|
| 정의 | 요소의 위치·크기·정렬이 바뀌어 레이아웃을 다시 계산하는 과정 | 레이아웃은 유지한 채 시각적 스타일만 다시 그리는 과정 |
| 변경 대상 | width, height, margin, padding, position 등 | color, background-color, box-shadow 등 |
| 레이아웃 계산 | 다시 계산함 | 다시 계산하지 않음 |
| 성능 비용 | 큼 | 상대적으로 작음 |
| 영향 범위 | 상위·하위 요소까지 연쇄 영향 | 해당 요소 중심 |
| 발생 관계 | 발생 시 Repaint를 동반함 | 단독 발생 가능 |
| 예시 | 요소 크기 변경, DOM 추가/삭제 | 색상 변경, 배경 변경 |
최적화 방법
- reflow를 유발하는 CSS 속성 사용을 최소화
- CSS 애니메이션 최적화
- 애니메이션에 transform과 opacity 속성만을 사용하는 것이 성능에 유리
- 애니메이션 요소의 위치를 absolute로 두기
- will-change 속성 사용
- will-change 속성: 미리 어떤 변화가 일어날지 브라우저에 알려줌으로써 최적화를 강화
요약
Reflow는 레이아웃 계산이 다시 일어나는 과정이고, Repaint는 레이아웃은 그대로 두고 화면을 다시 그리는 과정이다. Reflow가 Repaint보다 비용이 훨씬 크다.