- Published On
Reflow와 Repaint의 차이점
Reflow와 Repaint란?
Reflow
와 Repaint
는 브라우저가 웹 페이지를 렌더링할 때 발생하는 두 가지 주요 작업입니다.
이 작업들은 DOM(문서 객체 모델)의 변화에 따라 브라우저가 페이지를 다시 계산하고 화면에 표시하는 과정을 의미합니다.
Reflow란?
Reflow
는 DOM 요소의 레이아웃을 변경할 때 발생하는 과정으로, 브라우저가 요소들의 크기, 위치, 배치를 다시 계산하는 작업입니다. DOM 트리에 변화가 생기면 브라우저는 그에 맞춰 페이지의 레이아웃을 다시 계산해야 합니다.
- Reflow는 매우
비용이 큰 작업
입니다. DOM의 상위 노드에서 Reflow가 발생하면 해당 노드의자식 노드들
도 Reflow가 발생하며, 모든 관련 요소가 다시 계산됩니다. - 페이지 구조가 복잡할수록 Reflow는 더 많은 리소스를 요구하므로, 이를 최소화하는 것이 성능 최적화에 매우 중요합니다.
Repaint란?
Repaint
는 요소의 시각적 스타일
(색상, 배경색, 그림자 등)이 변경될 때 발생하는 과정으로, 요소의 배치는 그대로 유지되지만 화면에 그려지는 방식
이 변경됩니다. Repaint는 레이아웃을 다시 계산하지 않으므로 Reflow에 비해 비용이 적게 듭니다
.
- Repaint는 부모 노드와 자식 노드 간의 관계를 가지지 않으므로, 특정 요소에서 발생한 Repaint는
다른 요소에 영향을 주지 않습니다
.
Reflow와 Repaint의 차이점
특징 | Reflow | Repaint |
---|---|---|
작업 | 요소의 레이아웃(크기, 위치 등)을 다시 계산 | 요소의 시각적 스타일(색상, 테두리 등)만 다시 그리기 |
영향 범위 | 상위 노드에서 발생 시 하위 노드까지 영향을 미치며, 큰 범위에서 발생 | 특정 요소에만 발생하며, 다른 요소에 영향 없음 |
성능 비용 | 매우 높은 비용 (CPU 사용량이 큼) | 상대적으로 낮은 비용 |
발생 시점 | DOM 구조 변경, 요소의 위치나 크기 변화 시 | 색상, 배경색, 텍스트 스타일 등 시각적 변화 시 |
이러한 이유 때문에, Reflow를 최소화 해야됩니다.
속성
속성 | Reflow 유발 | Repaint 유발 |
---|---|---|
width , height | (요소 크기 변화로 인해 레이아웃 재계산) | |
padding , margin | (요소 간 간격 변경으로 레이아웃 영향) | |
position (top, left 등) | (요소 위치 변화로 인해 레이아웃 재배치) | |
color , background-color | (요소의 시각적 스타일만 변경됨) | |
box-shadow , text-shadow | (시각적 효과만 변경됨) | |
opacity , transform | (투명도만 변경됨), (요소의 위치나 크기가 시각적으로만 변경됨) |
Reflow를 최소화해야 하는 이유
Reflow는 레이아웃을 다시 계산하는 복잡한 과정이기 때문에, 성능에 매우 큰 영향을 미칩니다. 특히 페이지의 DOM 구조가 복잡하거나 대규모의 요소들이 존재할 경우, Reflow가 자주 발생하면 CPU 부하가 커지고, 페이지의 반응 속도가 저하될 수 있습니다. 따라서 Reflow를 최소화하는 것이 성능 최적화의 중요한 요소입니다.
Reflow를 최소화하기 위한 방법
React 코드를 기준으로 예시 코드를 통해 설명하겠습니다.
- DOM 조작 최소화:
React에서는 DOM을 직접 조작하지 않지만, 상태(state) 변경이 빈번하게 발생하면 렌더링이 자주 일어나 Reflow가 발생할 수 있습니다.
이를 해결하려면 상태 변경을 한 번에 묶어서
처리하는 것이 좋습니다.
// 잘못된 예시: 상태를 개별적으로 업데이트해 Reflow가 자주 발생
const Component = () => {
const [width, setWidth] = useState(100);
const [height, setHeight] = useState(200);
const handleResize = () => {
setWidth(150);
setHeight(300); // 상태를 개별적으로 업데이트해 렌더링이 자주 발생
};
return <div style={{ width: `${width}px`, height: `${height}px` }} />;
};
// 올바른 예시: 상태를 한 번에 업데이트해 Reflow 최소화
const Component = () => {
const [size, setSize] = useState({ width: 100, height: 200 });
const handleResize = () => {
setSize({ width: 150, height: 300 }); // 상태를 한 번에 업데이트해 렌더링 최소화
};
return (
<div style={{ width: `${size.width}px`, height: `${size.height}px` }} />
);
};
- CSS 스타일 변경 최소화:
React에서 인라인 스타일을 자주 변경할 경우 Reflow가 발생할 수 있습니다. 가능한 한 CSS 클래스를 활용하거나, 스타일 변경을 한 번에 처리하여 Reflow를 줄일 수 있습니다.
// 잘못된 예시: 스타일을 개별적으로 변경
const Component = () => {
const [style, setStyle] = useState({});
const handleStyleChange = () => {
setStyle((prev) => ({ ...prev, width: "150px" }));
setStyle((prev) => ({ ...prev, padding: "20px" })); // Reflow가 자주 발생
};
return <div style={style}></div>;
};
// 올바른 예시: 스타일을 한 번에 변경해 Reflow 최소화
const Component = () => {
const [style, setStyle] = useState({});
const handleStyleChange = () => {
setStyle({ width: "150px", padding: "20px" }); // Reflow를 최소화하기 위해 스타일을 한 번에 적용
};
return <div style={style}></div>;
};
- 애니메이션 최적화:
레이아웃에 영향을 미치지 않는 속성(예: opacity
, transform
)을 사용하여 애니메이션을 구현하면 Reflow를 방지할 수 있습니다.
// 올바른 예시: transform 속성으로 애니메이션 구현 (Repaint만 유발)
const Component = () => {
const [translate, setTranslate] = useState({ x: 0, y: 0 });
const handleMove = () => {
setTranslate({ x: 100, y: 50 }); // 레이아웃에 영향 없이 transform으로 처리
};
return (
<div
style={{ transform: `translate(${translate.x}px, ${translate.y}px)` }}
/>
);
};
- 클래스 추가/제거 최적화:
React에서 클래스를 동적으로 추가하거나 제거할 때도 Reflow가 발생할 수 있습니다. 클래스를 한 번에 변경하거나, 렌더링을 최소화하는 방식으로 Reflow를 줄일 수 있습니다.
// 잘못된 예시: 클래스를 개별적으로 변경
const Component = () => {
const [isActive, setIsActive] = useState(false);
const handleToggle = () => {
setIsActive(!isActive); // 클래스가 개별적으로 적용됨
};
return <div className={isActive ? "active" : "inactive"} />;
};
// 올바른 예시: 여러 클래스를 한 번에 적용
const Component = () => {
const [className, setClassName] = useState("inactive");
const handleToggle = () => {
setClassName(className === "inactive" ? "active" : "inactive"); // 클래스 변경을 한 번에 적용
};
return <div className={className} />;
};
결론
Reflow와 Repaint는 브라우저 렌더링 과정에서 필수적으로 발생하는 작업이지만, 그 처리 비용은 매우 다릅니다.
Reflow는 레이아웃 전체를 다시 계산해야 하기 때문에 성능에 큰 영향을 미치므로, 이를 최소화하는 것이 중요합니다.
이전 포스트
테스트 라이브러리 Cypress다음 포스트
랜더링(rendering)연관된 포스트 구경가기