25
프론트엔드 개발에 숨겨진 성능 비용 - Reflow & Repaint 자. 엄 두성

Reflow and repaint 성능 비용

Embed Size (px)

Citation preview

Page 1: Reflow and repaint 성능 비용

웹 프론트엔드 개발에 숨겨진 성능 비용

- Reflow & Repaint

발표자. 엄 두성

Page 2: Reflow and repaint 성능 비용

브라우저 렌더링 프로세스의 이해

• Rendering Engine Basic Flow :

브라우저가네트워크계층에서 요청된데이터를 받아오면

렌더링 엔진이 움직이기시작한다.

Page 3: Reflow and repaint 성능 비용

HTML Code

DOM Tree

documentElement(html)

head body

meta title style p div

CSS Code

Styles Structure

StylingInformation

cascades

Parse Parse

: 랜더링엔진에서코드를파싱하여 DOM Tree를생성

Page 4: Reflow and repaint 성능 비용

Render Tree

root(render view)

body

DOM TreeStyles

Structure

p

: DOM을화면에그리기위한정보들을 Rendering Tree로생성

Page 5: Reflow and repaint 성능 비용

Render Tree

root(render view)

body

p

: 생성된 Rendering Tree로 Element의위치나크기정보를생성

Page 6: Reflow and repaint 성능 비용

http://www.youtube.com/watch?v=nJtBUHyNBxs

http://www.youtube.com/watch?v=AKZ2fj8155I

: 생성된정보를바탕으로실제화면을그린다.

Page 7: Reflow and repaint 성능 비용

브라우저 렌더링 프로세스의 이해

Reflow Repaint

Page 8: Reflow and repaint 성능 비용

그렇다면..

화면구성이완료된 후 동적인 변화발생시엔?

• 특정엘리먼트의 Color 값에변화 발생

→ 해당엘리먼트의 Repaint 발생

• 엘리먼트의포지션에변화가발생

→ 해당엘리먼트의 Repaint + 레이아웃의 Reflow 발생

즉, 엘리먼트의폰트 사이즈를키우는단순한작업만추가 되더라도

전체 Render Tree의 Repaint와 Reflow를 유발

Page 9: Reflow and repaint 성능 비용

Reflow? Repaint?

• Repaint (or Redraw) :

1. 엘리먼트의 스킨에 변화가 발생하지만,

레이아웃에는 영향을 미치지 않을 때 유발

• Reflow :

1. 문서 내 노드들의레이아웃, 포지션을 재계산 후 다시 뿌림

2. Repaint 보다도 더 심각한 퍼포먼스 저하를 유발시키는 프로세스

Page 10: Reflow and repaint 성능 비용

무엇이 Reflow를 유발시키는가?

- 브라우저창 크기 수정

- DOM 트리 수정

- Style sheet 추가

- Style Property 수정

- 편집 ( 입력, ContentEditable )

- 등등..

Page 11: Reflow and repaint 성능 비용

Reflow 발생 example

Reflow 발생 그래프 :

단계별설명1.Click 이벤트2.Recalculate ( 변경된스타일수치 계산수행)3.Layout (Reflow 과정 수행)4.Paint (Repaint 과정 수행)

function reflow() {document.getElementById(‘container’).style.width=600px;

}

Page 12: Reflow and repaint 성능 비용

Reflow를 피하거나 그 영향을 최소화하는 방법

1. 애니메이션이들어간 노드는 position:fixed 또는

position:absolute로지정하여전체 노드에서분리

2. cssText 를 활용해 Reflow or Repaint 최소화

3. DOM 사용을 최소화하여 Reflow 비용 줄이기

4. 등등..

Page 13: Reflow and repaint 성능 비용

특정 노드의 Position 속성 변경 (1)

- position 속성을 "fixed" 또는 "absoute"로 값을 주면

해당 노드는 전체 노드에서 분리 됨.

즉, 전체 노드에걸쳐 Reflow 비용이들지 않으며,

해당 노드의 Repaint 비용만 들어가게됨.

Page 14: Reflow and repaint 성능 비용

특정 노드의 Position 속성 변경 (1)

테스트 코드:

<div id="container_animation“

style="background:blue;

position:absolute;

top:0px;left:0px;width:100px;height:100px;

border:red 1px solid;">

</div>

function animation() {document.getElementById('container_animation').style.left = '100px';document.getElementById('container_animation').style.top = '100px';return false;

}

Page 15: Reflow and repaint 성능 비용

특정 노드의 Position 속성 변경 (2)

테스트 결과:

Page 16: Reflow and repaint 성능 비용

cssText 를 활용해 Reflow 최소화 (1)

- DOM과 스타일 변경을하나로 묶어 Reflow 수행을

최소화 한다.

Page 17: Reflow and repaint 성능 비용

cssText 를 활용해 Reflow 최소화 (2)

case 1 : (Bad Case) 해당노드의 style 객체를여러번호출해적용

function collect() {var elem = document.getElementById('container');

elem.style.backgroundColor = 'red';elem.style.width = '200px';elem.style.height = '200px';

return false;}

Page 18: Reflow and repaint 성능 비용

cssText 를 활용해 Reflow 최소화 (3)

case 2 : style 객체 속성인 cssText를통해한번에적용.

function collect() {var elem = document.getElementById('container');

elem.style.cssText = 'background:red;width:200px;height:200px;';

return false;}

Page 19: Reflow and repaint 성능 비용

cssText 를 활용해 Reflow 최소화 (4)

테스트결과 :

상황별 Reflow 비용에드는시간.

Case 1 : 112ms

Case 2 : 104ms

Page 20: Reflow and repaint 성능 비용

DOM 사용을 최소화하여 Reflow 비용 줄이기(1)

- 노드 조각(document.createDocumentFragment),

노드 사본(elem.cloneNode) 을 활용하여 DOM 접근을

최소화 하여 비용을줄일 수 있다.

Page 21: Reflow and repaint 성능 비용

DOM 사용을 최소화하여 Reflow 비용 줄이기(2)

Case 1 : (Bad Case)

function notReflow() {

var elem = document.getElementById('container');

for (var i = 0; i < 10; i++) {var a = document.createElement('a');a.href = '#';a.appendChild(document.createTextNode('test' + i));elem.appendChild(a);

}

return false;}

Page 22: Reflow and repaint 성능 비용

DOM 사용을 최소화하여 Reflow 비용 줄이기(3)

Case 2 : 노드 조각을 활용한 엘리먼트 추가 방법

function notReflow() {

var frag = document.createDocumentFragment();

for (var i = 0; i < 10; i++) {var a = document.createElement('a');a.href = '#';a.appendChild(document.createTextNode('test' + i));frag.appendChild(a);

}

document.getElementById('container').appendChild(frag);

return false;}

Page 23: Reflow and repaint 성능 비용

DOM 사용을 최소화하여 Reflow 비용 줄이기(4)

Case 3 : 노드 사본을 활용한 엘리먼트 추가 방법

function notReflow() {

var elem = document.getElementById('container');var clone = elem.cloneNode(true);

for (var i = 0; i < 10; i++) {var a = document.createElement('a');a.href = '#';a.appendChild(document.createTextNode('test' + i));clone.appendChild(a);

}

elem.appendChild(clone);

return false;}

Page 24: Reflow and repaint 성능 비용

DOM 사용을 최소화하여 Reflow 비용 줄이기(5)

상황별 테스트 결과:

Case 1 : 153ms

Case 2 : 136ms

Case 3 : 129ms

Page 25: Reflow and repaint 성능 비용

Thank you