HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
👻
개발 기록
/
📚
CS 스터디
/
📚
reflow, repaint
📚

reflow, repaint

브라우저 렌더링 과정에서 일어나는 Reflow와 Repaint가 무엇인지 알아보자!
렌더링 과정을 정확하게 이해하면 어떤 코드가 성능이 좋은지 판단할 수 있다!
 

❓ 브라우저 렌더링은 어디서?

notion image
 
  • 렌더링 : HTML, CSS, JavaScript등 개발자가 작성한 문서를 브라우저에서 그래픽 형태로 출력하는 과정.
  • 모든 브라우저가 같은 렌더링 엔진을 사용하진 않음. 다르게 동작할 수 있음을 항상 유의하자!

렌더링 과정(간단하게)

notion image
  1. DOM(Document Object Model), CSSOM(CSS Object Model) 생성.
    1. 브라우저는 HTML, CSS를 해석 합니다. 그리고 HTML 문서의 해석이 끝나면 DOM 트리를 만들고, CSS 문서의 해석이 끝나면 스타일 규칙을 만듭니다.
  1. Render Tree 생성.
    1. DOM Tree와 CSSOM Tree를 이용해 Render Tree를 생성합니다. 순수한 요소들의 구조와 텍스트만 존재하는 DOM Tree와는 달리 Render Tree에는 스타일 정보가 설정되어 있으며 실제 화면에 표현되는 노드들로만 구성됩니다.
      notion image
      ⚠️
      실제 화면에 표현되는 노드? display: none 속성이 설정된 노드는 화면에 어떠한 공간도 차지하지 않기 때문에 Render Tree를 만드는 과정에서 제외됩니다. 추가로 visibility: invisible 은 display: none과 비슷하게 동작하지만, 공간은 차지하고 요소가 보이지 않게만 하기 때문에 Render Tree에 포함됩니다.
  1. Layout.
    1. 브라우저의 뷰포트(Viewport) 내에서 각 노드들의 정확한 위치와 크기를 계산합니다. 다시 말해, 생성된 Render Tree 노드들이 가지고 있는 스타일과 속성에 따라서 브라우저 화면의 어느위치에 어느크기로 출력될지 계산하는 단계입니다.
  1. Paint
    1. Layout 계산이 완료되면 요소들을 실제 화면을 그리게 됩니다. 이 때 처리해야 하는 스타일이 복잡할수록 Paint 단계에 소요되는 시간이 늘어나게 됩니다. 간단한 예시로 단색 background-color의 경우 paint 속도가 빠르지만, 그라데이션이나 그림자 효과 등은 painting 시간이 더 오래 소요됩니다.
 

🤔 Reflow

위에서 언급된 렌더링 과정을 거친 뒤에 최종적으로 페이지가 그려진다고 해서 렌더링 과정이 다 끝난것이 아닙니다. 어떠한 액션이나 이벤트에 따라 레이아웃(html 요소의 크기, 위치 등)을 수정하면 부모 노드들을 포함하여 그에 영향을 받는 자식 노드가 Layout 과정을 다시 수행하게 됩니다. 결국 Render Tree와 각 요소들의 크기와 위치를 다시 계산하게 됩니다. 이러한 과정을 Reflow라고 합니다.

Reflow가 발생하는 경우

  • 페이지 초기 렌더링 (최초 Layout 과정)
  • 윈도우 리사이징 (Viewport 크기 변경시)
  • DOM 노드의 추가, 제거
  • DOM 노드의 위치, 크기 변경 (margin, padding, border, width, height 등..)
  • 이미지 크기 변경
  • 폰트 변경, 텍스트 내용 변경
  • CSS3 애니메이션과 트랜지션
  • offset, scrollTop, scrollLeft과 같은 계산된 스타일 정보 요청
 
→ 화면의 구조가 변경되었다면 Reflow가 발생!
 

🖌️ Repaint

Reflow만 수행되면 실제 화면에 반영되지 않습니다. Render Tree를 다시 화면에 그려주는 과정이 필요합니다. 결국은 Paint 단계가 다시 수행되는 것이며 이를 Repaint 라고 합니다.
⚠️
무조건 Reflow 후 Repaint는 아님! background-color, visibility와 같이 레이아웃에는 영향을 주지 않는 스타일 속성이 변경되었을 때는 Reflow를 수행할 필요가 없기 때문에 Repaint만 수행하게 됩니다.
 

✨ Reflow 최적화

cssText로 스타일을 한 번에!

// bad const body = document.body; body.style.width = '50px'; body.style.height = '100px'; // good const body = document.body; body.style.cssText = 'width: 50px; heigh: 100px;';

innerHTML을 한 번에!

// bad const ulElement = document.getElementsByTagName('ul')[0]; for(let i=0; i<10; i++) { ulElement.innerHTML += `<li> list${i} </li>`; } // good const ulElement = document.getElementsByTagName('ul')[0]; let strHtml = ulElement.innerHTML; for(let i=0; i<10; i++) { strHtml += `<li> list${i} </li>`; } ulElement.innerHTML = strHtml;

visibility: invisible 보다 display: none

  • visibility invisible은 레이아웃 공간을 차지하기 때문에 reflow의 대상이 됩니다.
  • 하지만 display none은 Layout 공간을 차지하지 않아 Render Tree에서 아예 제외됩니다.
    • notion image
  • left, right, width, height 보다 transform을, visibility/display 보다 opacitiy를 사용하는 것이 성능 개선에 도움이 됩니다.

애니메이션이 있는 노드는 position을 fixed 또는 absolute로!

  • 애니메이션 효과는 많은 Reflow 비용이 발생합니다.
  • position 속성을 fixed 또는 absolute의 값을 줘서, 지정된 노드를 전체 노드에서 분리시켜 해당 노드만 Reflow가 발생하도록 제한시킬 수 있습니다.
  • 이미 position 값이 있다면 애니메이션 시작 fixed 또는 absolute로 변경하였다가 애니메이션 종료 후 다시 원복 시켜 렌더링을 최적화할 수 있습니다.

그 외

  • 퀄리티, 퍼포먼스의 타협점을 찾기.
  • <table> 속성 피하기.
  • IE의 CSS 표현식 사용X.
  • CSS 하위 선택자 최소화.
  • DOM 사용 최소화.
  • 캐시 활용.
💡
이 외에도 많은 방법이 있으니 검색해보셔도 좋겠습니다!
 
 
참고자료 : 브라우저의 이해 #1 Reflow, Repaint에 대하여 알아봅니다. 브라우저 렌더링 과정 - Reflow Repaint, 그리고 성능 최적화
[Browser] Reflow와 Repaint