본문 바로가기

기술면접

Reflow가 발생하는 이유와 방지 방법은 무엇인가요?

Reflow가 발생하는 이유

Reflow는 브라우저 렌더링을 위해 DOM 트리를 그리는 과정에서 발생합니다. 
생성된 DOM 노드의 레이아웃 수치(너비, 높이, 위치 등) 변경 시 영향 받은 모든 노드의(자신, 자식, 부모, 조상(결국 모든 노드) ) 수치를 다시 계산하여(Recalculate), 렌더 트리를 재생성하는 과정입니다.
Reflow가 일어나는 상황은 페이지 초기 렌더링(최초 layout 과정), 노드의 추가 혹은 제거, 요소의 위치나 크기 변경 (margin, padding, border, width, height 등), 폰트 변경과 이미지 크기 변경, 윈도우 리사이징이 있습니다.

Reflow 최적화 방법

이러한 reflow 발생비용을 최적화하기 위한 방법은 여러가지가 있습니다.
스타일을 변경할 경우 가장 하위 노드의 클래스만 변경하면 reflow가 일어나는 노드의 범위가 작아지기 때문에 최적화가 가능합니다. 하지만 이 방법은 작성되어있는 구조를 변경하기는 어렵기 때문에실무에서 적용할 수 있는 범위는 크지 않습니다.
두번째는, 인라인 스타일을 지양하는 것인데 그 이유는 HTML이 파싱되는 시점에서 바로 레이아웃에 영향을 미치기 때문에 추가적인 reflow를 발생시키기 때문입니다. 효율적인 파싱을 위해 관심사 분리가 중요하기 때문에 인라인 스타일 또한 지양하는게 좋습니다.
애니메이션이 있는 엘리먼트라면 position 속성을 fixed 혹은 absolute로 지정하는게 좋습니다. 그 이유는 애니메이션 효과는 계속 변경되어 많은 reflow를 발생시키기 때문에 해당 노드를 전체 노드에서 분리를 시켜 그 애니메이션에 해당되는 노드만 reflow를 발생시키도록 제한시킬 수 있기 때문입니다.
또한 <table> 태그는 마지막에 화면에 그려지기 때문에 조금만 변경이 있어도 모든 테이블의 너비가 다시 계산되어 reflow 비용이 많이 발생하기 때문에 <table> 태그 레이아웃을 지양하고, CSS 표현식을 지양하고, CSS 하위 선택자를 최소화하여 렌더링 트리 계산을 줄이고, display: none 속성을 활용하면 렌더트리에 제외가 되기 때문에 이 방법으로 스타일을 변경하고, 캐시를 활용하여 레이아웃 변경을 큐에 저장하여 한번에 실행하여 reflow를 최소화 하는 방법이 있습니다.
서비스를 만드는 회사는 성능 최적화에 우선순위를 두어야 합니다. 빠른 렌더링을 위해서는 여러가지 다양한 방법이 있지만, 리플로우와 리페인트를 최대한 줄이는 것이 성능 최적화의 좋은 방법 중 하나입니다.

또한, Reflow 과정이 끝난 후 재 생성된 렌더 트리를 다시 그리게 되는데 이 과정을 Redraw 혹은 Repaint 라 합니다.
하지만 레이아웃 수치가 변경이 되어야지만 redraw가 발생하는 것은 아닙니다.
노드의 background-color, visibility, outline 등의 색상관련 스타일이 변경되었을때에는 reflow를 제외하고 redraw만 일어나기도 합니다.


Reference
https://www.youtube.com/watch?v=XoyWzOh3Sy4 

반응형