Reflow & Repaint

angie·2023년 1월 18일
0

FE 관련 지식 쌓기

목록 보기
5/7

브라우저의 렌더링 과정

parsing → attachment → layout → paint → composite

  • parsing : DOM Tree, CSSOM Tree 생성
  • attachment(style) : DOM Tree, CSSOM Tree를 합쳐 Render Tree 생성
  • layout(Reflow) : Render Tree의 모든 노드들의 위치, 크기 등 정확한 값을 계산
  • paint : 계산된 렌더 트리를 화면상 기준으로
  • composite : 레이어를 합성하여 실제 화면을 그린다.

Reflow & Repaint

  • DOM의 노드 중 하나라도 변경사항이 생기면 전체 노드들이 다시 Reflow과정을 거치기 때문에 퍼포먼스 저하를 불러온다.

1. Reflow(Layout)

  • 브라우저 렌더링이 끝난 후 생성된 DOM 노드의 레이아웃 변경 시 영향 받은 모든 노드의 수치를 다시 계산하여(Recalculate) 렌더 트리를 재생성하는 과정

예시

  • 윈도우 리사이징
  • 노드 추가 혹은 제거
  • 내용 변화
  • JS를 통한 DOM의 변화
  • 요소의 크기, 위치 변경

2. Repaint

  • Reflow 과정이 끝난 후 재생성된 렌더 트리를 다시 그리는 과정이 Repaint

Reflow, Repaint 최소화

  • 렌더링 최적화를 위해 Reflow, Repaint를 최소화하는 것이 좋음

Reflow가 발생하는 경우

  • 윈도우 리사이징 (뷰포트 변화는 Global Layout에 영향)
  • 폰트의 변화 (height계산에 영향을 주므로 Global Layout에 영향)
  • 스타일 추가 또는 제거(레이아웃을 바꾸므로)
  • 내용 변화 (인풋박스에 텍스트 입력 등..)
  • :hover와 같은 CSS Pseudo Class(CSS: The Definitive Guide: The Definitive Guide 55p에서, hover할 시 나타나는 변화로 인한 우려가 생긴다는 의미인 듯 합니다.)
  • 클래스 Attribute의 동적 변화
  • JS를 통한 DOM 동적 변화
  • 엘리먼트에 대한 offsetWidth / offsetHeight (화면에서 보여지는 좌표) 계산시
  • 스타일 Attribute 동적변화

최소화하는 방법

  1. 클래스 변화에 따른 스타일 변화를 원할 경우, 최대한 DOM 구조 상 끝단에 위치한 노드에 적용하기
  2. 인라인 스타일 피하기
  3. 애니메이션이 들어간 엘리먼트는 가급적 position:fixed 혹은 position:absolute로 지정
  4. 퀄리티와 퍼포먼스 사이에서 타협하라.
  5. 테이블 레이아웃을 피하기
  6. IE의 경우, CSS에서 JS표현식 피하기
  7. JS를 통해 스타일 변화를 주어야 할 경우, 가급적 한번에 처리하기
  8. CSS Rules는 필요한 만큼 정리하기
  9. position:relative 사용시 주의

1. 클래스 변화에 따른 스타일 변화를 원할 경우, 최대한 DOM 구조 상 끝단에 위치한 노드에 적용하기

  • DOM 트리에서 말단에 위치한 노드에 클래스 변화를 주면 Reflow의 행동반경을 전체 페이지가 아닌 일부 노드들로 제한할 수 있음
  • 전체 페이지를 감싸는 wrapper에 클래스를 수정하는 행위는 피해야함

2. 인라인 스타일 피하기

  • 인라인 스타일이 있는 경우 Reflow는 페이지 전체에 걸쳐 수차례 발생

3. 애니메이션이 들어간 엘리먼트는 가급적 position:fixed 혹은 position:absolute로 지정

  • JS (특히 JQuery)나 CSS3로 width, height 또는 위치이동을 구현한 애니메이션은 초단위로 상당한 Reflow를 발생시킴
  • 해당 개체의 position 속성을 fixed 혹은 absolute로 주게 되면 다른 레이아웃에 영향을 끼치지 않아 해당 요소만의 Repaint를 유발

4. 퀄리티와 퍼포먼스 사이에서 타협하라.

  • 애니메이션의 계산과 페이지 Reflow 계산이 동시다발적으로 발생하여 CPU 퍼포먼스 비용이 발생
  • 1초에 1px 움직이는 애니메이션 A와 1초에 3px 움직이는 애니메이션 B 중 A가 B에 비해 훨씬 큰 비용 발생

5. 테이블 레이아웃을 피하기

  • 테이블로 구성된 페이지의 레이아웃은 점진적으로 페이지 렌더링이 진행되지 않음
  • 모두 로드되고 계산된 후에야 화면에 뿌려짐
  • 테이블 레이아웃에서는 아주 작은 변화마저도 해당 테이블 전체에 모든 노드에 대한 Reflow를 발생시킴
  • 테이블에 table-layout: fixed 속성을 주면 디폴트값인 auto에 비해 성능면에서 유리

6. IE의 경우, CSS에서 JS표현식 피하기

  • Reflow될 때마다 CSS 표현식이 다시 계산되기 때문에 CSS 표현식의 비용이 매우 높음

7. JS를 통해 스타일 변화를 주어야 할 경우, 가급적 한번에 처리하기

// Bad
var toChange = document.getElementById('elem');
toChange.style.background = '#333';
toChange.style.color = '#fff';
toChange.style.border = '1px solid #ccc';

// Good
/* CSS */
#elem { border:1px solid #000; color:#000; background:#ddd; }
.highlight { border-color:#00f; color:#fff; background:#333; }
/* js */
document.getElementById('elem').className = 'highlight';

8. CSS Rules는 필요한 만큼 정리하기

/* 예시 1*/
.section_service .list_service li .box_name .btn_more {display:block;width:100px;height:30px;}

/* 예시2 */
.section_service .list_service .btn_more {display:block;width:100px;height:30px;}

두 예시 모두 같은 요소를 선택하는 CSS 선택자

  • 같은 요소를 선택하지만 예시1이 더 많은 선택자를 사용하므로써 퍼포먼스가 하락
  • 두번째 예처럼 딱 필요한 선에서 핵심만 짚는 CSS Rules 선언 필요

9. position:relative 사용시 주의

  • position:relativeposition:absolute, float보다 큰 비용 발생
  • 이유는 Box model → Normal flow → Positioning의 3단게를 모두 거치기 때문

Virtual DOM

  • 이러한 Reflow로 인한 문제를 해결하기 위해 Virtual DOM이 고안됨
  • 메모리에 Virtual DOM을 저장하고 DOM의 변화가 생겼을 때 이전에 저장된 가상돔과 새로 그려야하는 가상돔을 비교하여 변경된 부분만을 실제 DOM에 반영
profile
better than more

0개의 댓글