Reflow와 Repaint는 무엇인가?
Reflow는 특정 액션이나 이벤트에 의해서 DOM에 존재하는 Element의 크기나 위치가 변경될 경우
영향을 받는 모든 Element의 너비, 높이와 같은 모든 수치를 다시 계산하는 과정이다.
Repaint는 Reflow가 끝난 후 사이즈가 모두 계산된 렌더 트리를 가지고 화면에 Element들을 다시 그리기 시작하는데
이 동작을 Repaint라고 한다.
Repaint는 Reflow가 일어난 후에만 수행되는 것이 아니라 color, background-color와 같이
Element의 수치가 변경되지 않는 스타일을 변경할 경우 Reflow는 일어나지 않지만 Repaint는 발생하게 된다.
브라우저의 렌더링 과정과 함께 보는 Reflow, Repaint
위의 그림은 웹 브라우저의 렌더링 과정인 CRP(Critical Rendering Path)를 간단하게 나타낸 것이다.
- HTML과 CSS를 파싱하여 DOM Tree와 CSSOM Tree를 생성한다.
- Javascript를 실행시켜 시각적인 요소의 변경을 일으키는 작업을 수행한다.
- DOM Tree와 CSSOM Tree를 결합하여 Render Tree를 생성한다.
Render Tree를 생성할 때 display: none이나 head Tag와 같이 화면상에 나타나지 않는 요소들은 화면에 그릴 필요가 없기 때문에
Render Tree에서 제외된다. - Render Tree에 존재하는 각 노드들의 구체적인 위치와 크기들을 계산한다.
이 과정을 Layout 혹은 Reflow이라고 부른다. - 생성된 Layout Tree를 사용하여 브라우저 화면에 Rendering 한다.
이 과정을 Paint라고 한다. 만약 처음에 Paint된 상태에서 Reflow가 일어나 화면을 다시 그리게 된다면 이를 Repaint라고 부르기도 한다. - 위의 과정을 거쳐 생성된 여러 Render Tree들을 하나로 합친다.
현대적인 웹 페이지들은 단순히 정적인 텍스트를 보여주던 고대의 웹 페이지들과는 다르게 사용자의 입력에 따라 상호 작용을 하며
매우 동적인 작업을 수행한다, 그렇기 때문에 사실상 Repaint는 피할 수 없으며 최소한 Reflow 발생을 최소화 하도록 노력해야 한다.
Reflow 발생을 최소화 하는 방법
- Animation이 발생하는 Element는 position을 fixed나 absolute로 적용하자
absolute나 fixed로 지정할 경우 다른 요소들에는 영향을 끼치지 않으므로 모든 Element가 아닌
해당 Element에만 reflow가 발생한다. - JS를 통해서 스타일을 변경할 경우 한 번에 처리하자
여러번 나누어 변경할 경우 reflow 연산이 여러번 발생할 수 있다. - inline 스타일을 최대한 사용하지 않는다. (2번과 같은 이유)
- Table layout은 필요한 경우에만 사용하자
Table layout은 테이블안의 요소 값에 따라 넓이를 계산하여 reflow 작업이 느려지게 된다.
table-layout: fixed를 사용하연 조금 더 빠르게 사용하는 것이 가능하다. - 스타일의 변경이 필요하다면 최하위 노드를 변경하자
부모 Element는 reflow가 일어나지 않도록 하는 것 - will-change를 적용하자
will-change는 해당 요소의 어떤 값이 변할 수 있다고 브라우저가 예측할 수 있도록 해준다.
https://developer.mozilla.org/ko/docs/Web/CSS/will-change 참조
만약 지금 사용하고 있는 스타일 속성들을 변경했을때 어떤 과정이 일어나는지 예측이 안된다면
https://csstriggers.com/ 이 곳을 참조하자