8. 그렇다면..
화면구성이 완료된 후 동적인 변화발생 시엔?
• 특정 엘리먼트의 Color 값에 변화 발생
→ 해당 엘리먼트의 Repaint 발생
• 엘리먼트의 포지션에 변화가 발생
→ 해당 엘리먼트의 Repaint + 레이아웃의 Reflow 발생
즉, 엘리먼트의 폰트 사이즈를 키우는 단순한 작업만 추가 되더라도
전체 Render Tree의 Repaint와 Reflow를 유발
9. Reflow? Repaint?
• Repaint (or Redraw) :
1. 엘리먼트의 스킨에 변화가 발생하지만,
레이아웃에는 영향을 미치지 않을 때 유발
• Reflow :
1. 문서 내 노드들의 레이아웃, 포지션을 재계산 후 다시 뿌림
2. Repaint 보다도 더 심각한 퍼포먼스 저하를 유발시키는 프로세스
10. 무엇이 Reflow를 유발시키는가?
- 브라우저 창 크기 수정
- DOM 트리 수정
- Style sheet 추가
- Style Property 수정
- 편집 ( 입력, ContentEditable )
- 등등..
11. Reflow 발생 example
Reflow 발생 그래프 :
단계별 설명
1.Click 이벤트
2.Recalculate ( 변경된 스타일 수치 계산 수행)
3.Layout (Reflow 과정 수행)
4.Paint (Repaint 과정 수행)
function reflow() {
document.getElementById(‘container’).style.width=600px;
}
12. Reflow를 피하거나 그 영향을 최소화하는 방법
1. 애니메이션이 들어간 노드는 position:fixed 또는
position:absolute로 지정하여 전체 노드에서 분리
2. cssText 를 활용해 Reflow or Repaint 최소화
3. DOM 사용을 최소화하여 Reflow 비용 줄이기
4. 등등..
13. 특정 노드의 Position 속성 변경 (1)
- position 속성을 "fixed" 또는 "absoute"로 값을 주면
해당 노드는 전체 노드에서 분리 됨.
즉, 전체 노드에 걸쳐 Reflow 비용이 들지 않으며,
해당 노드의 Repaint 비용만 들어가게 됨.
14. 특정 노드의 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;
}
16. cssText 를 활용해 Reflow 최소화 (1)
- DOM과 스타일 변경을 하나로 묶어 Reflow 수행을
최소화 한다.
17. 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;
}
18. 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;
}
19. cssText 를 활용해 Reflow 최소화 (4)
테스트 결과 :
상황 별 Reflow 비용에 드는 시간.
Case 1 : 112ms
Case 2 : 104ms
20. DOM 사용을 최소화하여 Reflow 비용 줄이기(1)
- 노드 조각(document.createDocumentFragment),
노드 사본(elem.cloneNode) 을 활용하여 DOM 접근을
최소화 하여 비용을 줄일 수 있다.
21. 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;
}
22. 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;
}
23. 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;
}
24. DOM 사용을 최소화하여 Reflow 비용 줄이기(5)
상황별 테스트 결과:
Case 1 : 153ms
Case 2 : 136ms
Case 3 : 129ms