차근차근 개발중

[WEB] 리플로우(reflow)와 리페인트(repaint) 본문

개발/WEB

[WEB] 리플로우(reflow)와 리페인트(repaint)

zaenny 2025. 2. 27. 11:33
렌더링 과정중에 성능최적화를 고민하기위해서는 리플로우와 리페인트단계를 빼놓을 수 없다 
그렇기때문에 리플로우와 리페인트에 대해서 공부해보자 

 

 

화면이 사용자에게 표출된 후에 노드가 추가되거나 요소의 스타일이 달라졌을때 발생하는게 리플로우(Reflow)와 리페인트(Repaint)입니다 

 

📌 리플로우란(Reflow)?

- 요소의 위치나 크기가 변경되어 페이지의 레이아웃을 다시 계산하는 과정입니다. 변경하려는 특정요소의 위치와 크기뿐만 아니라 연관된 요소들의 위치와 크기도 재계산하기 때문에 성능 저하가 일어납니다. 

 

 발생원인

  • DOM요소 추가/ 제거
  • 요소의 크기, 위치 변경
  • 폰트변경, 텍스트 내용변경
  • 윈도우 크기조정 
  • css 스타일 변경 ex) margin, padding등 

 특징

  • 계산 비용이 높다
  • 하나의 요소가 리플로우가되면 그 자식 요소와 부모 요소도 영향을 받을 수 있다.

 성능 최적화 팁

  • 여러 DOM변경을 한 번에 처리합니다. 
// 나쁜 예 - 리플로우 여러 번 발생
const element = document.getElementById('box');
element.style.width = '100px';
element.style.height = '100px';
element.style.margin = '10px';

// 좋은 예 - 리플로우 한 번만 발생
const element = document.getElementById('box');
element.style.cssText = 'width: 100px; height: 100px; margin: 10px;';

// 또는 클래스 사용
element.className = 'new-box';

 

  • 여러 요소를 추가할 때 메모리에서 작업 후 한 번에 DOM에 삽입
// 나쁜 예 - 각 항목마다 리플로우 발생
const list = document.getElementById('list');
for (let i = 0; i < 100; i++) {
  const item = document.createElement('li');
  item.textContent = `항목 ${i}`;
  list.appendChild(item); // 매번 리플로우 발생
}

// 좋은 예 - 리플로우 한 번만 발생
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const item = document.createElement('li');
  item.textContent = `항목 ${i}`;
  fragment.appendChild(item);
}
list.appendChild(fragment); // 리플로우 한 번만 발생

※ DocumentFragment는 메모리 상에만 존재하는 경량화된 DOM 조각입니다. 실제 DOM에 직접 연결되어 있지 않기 때문에, DocumentFragment에 변경 사항을 추가해도 라이브 DOM에 영향을 주지 않습니다.

  • position: absolute/fixed 활용하기
/* 절대 위치를 사용하면 이 요소의 변경이 다른 요소에 영향을 미치지 않음 */
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  /* 변경해도 다른 요소에 리플로우 영향 최소화 */
}

 

📌 리페인팅이란(Repainting)?

- 요소의 시각적인 스타일만 변경되어 화면을 다시그리는 과정입니다. 레이아웃에는 영향을 주지 않습니다. 

• 발생원인

  • 색상, 투명도, 그림자 효과 변경
  • visibility 속성변경 

  특징

  • 리플로우보다 비용이 적음
  • 레이아웃에는 영향을 주지 않음
  • 리플로우가 일어났을때 리페인팅은 항상 유발되지만 리페인팅은 항상 리플로우를 유발하지는 않습니다. 

 리페인팅(Repainting) 성능 최적화 팁

  • 여러 스타일 변경을 한 번에 적용하기
// 나쁜 예 - 여러 번의 리페인팅 발생
const element = document.getElementById('box');
element.style.backgroundColor = 'red';
element.style.color = 'white';
element.style.boxShadow = '2px 2px 5px #999';

// 좋은 예 - 한 번의 리페인팅만 발생
element.style.cssText = 'background-color: red; color: white; box-shadow: 2px 2px 5px #999;';
// 또는 클래스 추가
element.classList.add('styled-box');

 

  • 화면에 보이지 않는 요소나 중복 요소 제거하기
// 가상 스크롤링 구현 예시 - 화면에 보이는 요소만 렌더링
function renderVisibleItems(scrollPosition) {
  const container = document.getElementById('container');
  container.innerHTML = ''; // 기존 내용 지우기
  
  const visibleItems = allItems.slice(
    Math.floor(scrollPosition / itemHeight),
    Math.ceil((scrollPosition + viewportHeight) / itemHeight)
  );
  
  visibleItems.forEach(item => {
    const element = document.createElement('div');
    element.textContent = item.text;
    container.appendChild(element);
  });
}

 

  •  JavaScript보다 CSS 트랜지션 활용하기
css
.button {
  background-color: blue;
  transition: background-color 0.3s ease;
}

.button:hover {
  background-color: darkblue;
}


javascript
// 나쁜 예 - JavaScript로 색상 변경
element.addEventListener('mouseover', function() {
  element.style.backgroundColor = 'darkblue';
});

// 좋은 예 - CSS 클래스 토글로 처리 (브라우저 최적화 활용)
element.addEventListener('mouseover', function() {
  element.classList.add('hover');
});
Comments