Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
자바스크립트 성능 최적화 기법- 한국마이크로소프트 기술지원부 이진헌 과장
2014년 2월웹클라이언트개발환경에풍성함을더하다!
성능 문제의 배경
성능 문제의 대표적인 증상
자바스크립트 실행 환경의 이해
최적화 방식 소개
각 브라우저의 자바스크립트 성능 비교빠른브라우저는프론트앤드웹개발분야의발전기반
26x Faster
자바스크립트의 양적 증가 추세전세계웹사이트를구성하는평균자바스크립트크기
출처:httparchive.org
• 3년간 2배 이상증가
• 평균을 크게상회하는웹사이트가 증가
다양한 브라우저 버전 점유율Modern browser vs. Legacy browser (한국)
출처:statcounter.com
IE8 34.1%
IE9 21.8%
Chrome 20%
IE10 16.3%
ZZZZZZ
Windows Performance ToolkitXperf
IE11 - F12 Developer toolUI Responsiveness
Networking Parsing
Loading
1
2 7
43 8 9
5 6
DOM
Tree
Formatting Layout
ScriptingScripting
GC
Styling
1
2 7
43 8 9
5 6
Display Tree
Painting
Rendering
Compositing
Decoding
http://ie.microsoft.com/testdrive/Performance/Popcorn/
단일 쓰레드
단일 이벤트 큐
• DOM
• 레이아웃
• Native code
코드를 최적화
(예외: Web Worker)
loadevent
page loadevent handler
timerevent
timer
EH
timerevent
timer
EH
timerevent
timer
EH
clickevent
mouse clickevent handler
timerevent
timerevent
timer
EH
timerevent
timer
EH
timer
EH
timerevent
UI Update(Button)
Event Handler(click)
Event Handler(click)
Event Handler(Timer)
UI Update(Button)
Event Handler(click)
Event Handler(Timer)
UI Thread
Event Queue
• 루프문에서는 DOM 메소드 호출을 최소화
• DOM을 조작하는 작업은 모아서 한 번에 처리
<div>
<div> <div> <div> <div>
<div>
<div> <div> <div>
<div>
Reflow
<div>
<div> <div> <div> <div>
<div>
<div> <div> <div> <div>Repaint
vs.
31 bits
Object pointer1 bit
032 bits
32 bits
Floats32-bit
Integers
31 bits
31-bit (tagged) Integers1 bit
1
STACK HEAP
IEEE 64비트 부동소수점을 표현하는Wrapper Object
STACK
vs.
function doMath() {var a = 5;var b = 2;r = ((a + b) / 2); // 3.5
}var intR = Math.floor(r);
function doMath() {var a = 5;var b = 2;r = ((a + b) / 2) | 0; // 3r = Math.round((a + b) / 2); // 4
}
SLOW FAST
0x005e4148r: Number
3.5
STACK HEAP
0x00000007r:
0x00000009r:
STACK
var a = new Array(10000);
for (var i = 0; i < a.length; i++) {a[i] = i;
}a[9999] = “str”;
var a = new Array(10000);
a[0] = “hint”;for (var i = 0; i < a.length; i++) {a[i] = i;
}a[9999] = “str”;
SLOW FAST
1
var a = new Array();
a[0] = 1;a[1] = 2.3;a[2] = “str”;
1 2.3
1 2.3 “str”
var value = 5;
var a = new Array(100);a[0] = value; // 5 - taggeda[1] = value / 2; // 2.5 - boxeda[2] = "text"; // "text" - var array
var value = 5;
var a = new Float64Array(100);a[0] = value; // 5 - no tagging requireda[1] = value / 2; // 2.5 - no boxing requireda[2] = "text"; // 0
var a = new Int32Array(100);a[0] = value; // 5 - no tagging requireda[1] = value / 2; // 2 - no tagging requireda[2] = "text"; // 0
SLOW FAST
var a = new Array(100);var total = 0;
for (var item in a) {total += item;
};
a.forEach(function(item){total += item;
});
for (var i = 0; i < a.length; i++) { total += a[i];
}
var a = new Array(100);var total = 0;var cachedLength = a.length;
for (var i = 0; i < cachedLength; i++) { total += a[i];
}
SLOW FAST
64xFaster
전세계 jQuery 점유율 통계
jQuery
none
$("#grid span.title") $("#grid").find("span.title")
WORSE BETTER
$("div#grid table tr td span.title") $("#grid span.title")
$("div.data .person").attr({"width": 500, "height": 500})
$("div.data .person").attr("width", 500)$("div.data .person").attr("height", 500)
$("[name='baz']")$(":hidden")
$("#bazid")$(".hidden")
vs.
var html = $('<div/>');
for (var i = 0; i < len; i++) {html.append($('<div>Test ' + i + '</div>'));
}
$('#list').append(html);
var list = document.getElementById('list');var div = document.createElement('div');
for (var i = 0; i < len; i++) {div.appendChild(document.createTextNode('Test ' + i));
}
list.appendChild(div);
SLOW? FAST?
http://jsperf.com/jquery-append-vs-html-list-performance/77
vs.
48xFaster
$('table td').click(function() {$(this).toggleClass('active');
});
$('table').on('click', 'td', function() {$(this).toggleClass('active');
});
SLOW FAST
http://jsperf.com/jquery-event-delegation/5
<table>
<tr><td></td>...<td></td></tr>
<tr><td></td>...<td></td></tr>
...
<tr><td></td>...<td></td></tr>
</table>
<table>
<tr>
<td> <td>
<td> <td>
//jQuery$('table').on('click', 'td', function() {$(this).toggleClass('active');
});
//pure javascripttable.onclick = function(event) {event = event || window.event;var target = event.target ||
event.srcElement;while(target != table) {if (target.nodeName == 'TD') {
toggleClass(target);}target = target.parentNode;
}}
20xFaster