리플로우(Reflow)와 리페인트(Repaint)

hzn·2022년 11월 21일
0

HTML & CSS

목록 보기
5/10
post-thumbnail

만약 사용자가 브라우저 화면을 늘리거나 줄이는 등 크기를 조절하거나, 다른 사이트로 이동을 하는 등 화면에 요소가 추가 되거나 삭제, 혹은 아예 다른 요소들을 불러와야 하는 상황이라면..
👉🏽 화면에 나타나는 모습을 바꾸기 위해서는 모든 요소의 위치와 크기를 다시 계산하고, 다시 그려 보여주어야 한다

리플로우

  • 어떤 웹 인터랙션으로 인해 렌더링 과정의 레이아웃을 반복해 수행하는 것을 리플로우라고 한다.

리페인트

  • 어떤 웹 인터랙션으로 인해 (리플로우 이후) 페인트 과정을 반복해 수행하는 것을 리페인트라고 한다.
  • 리플로우 시 리페인트는 필연적으로 일어난다.

리플로우, 리페인트의 예 : DOM 조작

  • DOM 조작은 리플로우, 리페인트가 일어나는 대표적인 예시이다.

1) JavaScript 조작을 통해 변경이 일어나면, DOM 트리를 다시 구성한다.
2) CSSOM과 합쳐 새 렌더 트리를 생성한다.
3) 레이아웃과 페인트 과정을 또 다시 거쳐 화면에 보여준다.

const div = document.createElement('div');
document.body.append(div);
div.textContent = 'hello world';
  • div요소를 생성하고 body에 해당 요소를 붙인 뒤 ‘hello world’라는 텍스트를 추가하는 코드
  • JavaScript를 통해 DOM을 조작한 것

리플로우와 리페인트의 최적화

  • 사용자의 눈에 일련의 과정이 부드럽게 처리 되려면 최소 초당 60 프레임은 필요
    (브라우저가 1초에 60장 가량의 레이아웃과 페인트 과정을 동시에 처리해야만 한다.)
  • DOM은 변경될 때마다 (렌더 트리를 다시 구축하기 때문에) 리플로우와 리페인트를 다시 해야 한다.
  • 리플로우 : 배치를 위한 연산(렌더링) 다시 하는 것이므로 CPU를 많이 차지
  • 리페인트 : 페인트를 다시 하는 것이라 픽셀을 다시 화면에 찍어 그려야 하기 때문에 GPU를 많이 차지

프레임 드랍

  • 초당 60프레임으로 유지시키던 프레임의 수가 브라우저의 과부하로 인해 줄어드는 현상
  • 드랍된(= 없어진) 프레임은 렌더링 엔진이 인식할 수 없어 브라우저 화면에 그리지 못한다. ( = "화면이 멈춘다, 버벅인다")
  • 프레임 드랍을 방지하기 위해 최적화가 필요

1. 불필요한 레이아웃을 줄인다.

  • CSSOM 트리의 CSS 속성 중에 레이아웃을 발생시키는 속성들이 존재하고 있는데, 이런 속성을 줄인다.

CSS에서 레이아웃/페인트를 발생시키는 속성들

  • 리플로우 시 리페인트는 필연적으로 일어나므로 가능하다면 리플로우가 발생하는 속성보다 리페인트만 발생하는 속성을 사용해주는 게 좋다.
    (페인트 과정은 유저에게 화면을 보여주기 위해 그리는 과정이라 필수적이므로 대신 최대한 레이아웃 과정을 줄인다.)

리플로우가 일어나는 대표적인 속성

  • 대개 위치, 혹은 너비와 관련된 속성
  • Ex) left 속성 중 left-top, left-bottom 속성을 사용하는 경우 (position 속성과 같이 사용)
    👉🏽 left 속성은 인터렉션 시 레이아웃을 발생시키는 속성이기 때문에 애니메이션을 만들 때는 프레임 유지를 보장하기 어려워진다.
    👉🏽 이 속성을 피해 transform이라는 속성을 사용한다. transform에 있는 translate를 사용하면 좌표 값을 사용해 위치를 이동하지만, 레이아웃을 발생시키지 않고 페인트만 다시 발생시키는 쪽으로 렌더링 과정이 일어나기 때문에 유지하고자 하는 프레임 수를 기대할 수 있다.

리페인트가 일어나는 대표적인 속성

  • 리페인트가 일어나지 않게 해주는 opacity라는 속성
  • visibility/display 대신 opacitiy를 사용하는 것이 성능 개선에 도움이 된다.

2. 영향을 주는 노드를 줄인다

  • JavaScript + CSS를 조합한 애니메이션이 많거나, 레이아웃 변화가 많은 요소의 경우 positionabsolute 또는 fixed를 사용해주면 영향을 받는 주변 노드들을 줄여줄 수 있다.
  • fixed와 같이 영향을 받는 노드가 전혀 없는 경우 리플로우 과정이 필요 없기 때문에 리페인트 연산 비용만 들일 수 있습니다.

0개의 댓글