자바스크립트 성능 이슈
1. 스코프 관리
- 식별자 해석
- 지역 변수가 빠르다.
- 체인이 깊어질 수록 더 느려진다.
- 스코프 체인 증가
- with 문
- try-catch 문의 catch 절
- -> 둘 다 스코프 체인의 앞에 객체를 추가한다.
- 권장사항
- 지역 변수에 out-of-scope 변수를 저장하라 (특히 전역 변수)
- with 문을 피하라
- 스코프 체인에 다른 객체를 추가한다. 따라서 지역 함수 변수들은 바로 한 단계 멀어진다.
- 대신에 지역 변수를 사용하라 - try-catch 문을 조심히 사용하라
- catch 절 또한 스코프 체인이 증가시킨다. - 클로저closures를 조금만 사용하라
- 변수를 선언할 때 var를 잊지 말아라
2. 데이터 접근
- 데이터 접근 성능
- 문자(literal)나 지역변수로 부터 데이터 접근이 가장 빠르다. 문자와 지역 변수 사이에 차이는 대부분의 경우에 무시해도 된다.
- 객체 속성이나 배열 아이템으로 부터 데이터 접근이 더 비싸다. Accessing data from an object property or array item is more expensive
- 이것은 브라우저에 의해 결정된다.
※ 챠트(동영상 17:19) 내용으로 보아 Firfox 3.1, Chrome2, Safari4 이상은 literal, local과 데이터 접근 속도가 0에 가까운 정도로 매우 빠름 (Opera10은 차이는 작지만 데이터 접근 속도는 20~30사이, IE7,8은 차이가 30정도로 크고 접근 속도 자체가 40이상) - 속성 깊이
- object.name < object.name.name
- 깊어진 속성일수록 검색하는 시간이 더 오래 걸린다. (IE7,8이 가장 가장 느려짐)
- 속성 표기법
- object.name 과 object["name"] 사이에 다른 점은?
- 일반적으로 없다.
- 예외 : Safari에서는 도트 표기법이 더 빠르다.
- object.name 과 object["name"] 사이에 다른 점은?
- 권장사항
- 이것들을 지역 변수에 저장하라.
- 한 번 이상 접근하는 객체 속성
- 한 번 이상 접근하는 배열 아이템 - 속성/배열 아이템 색인 깊이를 최소화하라.
function process(data){ if(data.count>0){ for (var i=0;i<data.count;i++){ processdata(data.item[i]); } } }
아래와 같이 변경한 결과 FF – 5%, Safari -10%, IE -33% 속도 향상function process(data){ var count = data.count, item = data.item; //지역 변수로 지정 if(data.count>0){ for (var i=0;i<data.count;i++){ processdata(data.item[i]); } } }
- 이것들을 지역 변수에 저장하라.
3. 반복문
- ECMA-262, 3rd Edition
- for, do-while, while
-for in - 문제가 무엇인가요?
- ?반복 당 작업 종료 양(Amount of work done per iteration) – terminal condition evaluation과 증가/감소를 포함
- 반복 횟수
- 이것은 루프 타입에 따라 바뀌지 않는다.
- 반복문 고치기
- 반복 당 작업량을 줄여라 Decrease amount of work per iteration
- 반복 횟수를 줄여라
- 쉽게 고치기
- 객체 속성/배열 아이템 검색을 제거해라for (var i=0;i<values.length;i++){ process(values[i]); } var j=0; do { process(values[j++]); } while ( j < values.length);
아래와 같이 지역 변수에 저장하여 반복 조건에서 객체 속성 검색을 제거var len = values.length; for (var i=0;i<len;i++){ process(values[i]); } var j=0; do { process(values[j++]); } while ( j < len);
- 제어 조건과 제어 변수 변경을 결합하라 Combine control condition and control variable change
- 속도를 위해 회피할 것들
- ECMA-262, 3rd Edition : for-in
- ECMA-357, 2nd Edition : for-each
- ECMA-262, 5th Edition : array.forEach()
- 함수 기반 반복문: jQuery.each(), Y.each(), $each,Enumerable.each()
4. DOM
- HTMLCollection Objects
- document.images, document.forms, etc.
- getElementsByTagName() – 도큐먼트의 모든 div엘리먼트를 요청하면 도큐먼트는 div엘리먼트에 변경이 발생할 때 마다 업데이트 하므로 계속해서 요청이 발생한다.
- getElementsByClassName()
- 배열처럼 보이지만 아닌 것들
- 괄호 표기법
- length 속성 - 특정 쿼리의 결과를 나타낸다
- 쿼리는 객체에 접근할 때 마다 매 번 재실행 된다.
- length와 특수한 항목에 접근하는 것을 포함
- 동일한 배열에 접근하는 것 보다 많이 느리다.
- 예외:Opera, Safari
var items = [{},{},{}, ...,{}]; for (var i=0; i<items.length;i++){ } var divs = document.getElementsByTagName("div"); for (var i=0; i<divs.length;i++){ }
=> FF 15배, Chrome 53배, IE 68배 느려짐아래와 같이 지역 변수에 저장하여 변경하면var items = [{},{},{}, ...,{}]; for (var i=0, len=items.length ; i< len ;i++){ } var divs = document.getElementsByTagName("div"); for (var i=0, len=divs.length ; i< len ;i++){ }
=> 느려지지 않음- 속성 접근을 최소화하라
- 자주 사용하는 경우 지역 변수에 length와 항목들을 저장하라
- 자주 순차적으로 항목들에 접근하려면 규칙적인 배열 안에 복사해라
fuction array(items){ try{ return Array.prototype.concat.call(items); } catch(ex){ var i = 0, len = items.length, result = Array(len); while (i<len){ result[i] = items[i]; i++; } return result; } }
- When Reflow?
- 처음 페이지를 불러올 때
- 브라우저 창 크기가 변경될 때
- DOM 노드가 추가되거나 제거될 때 ex) list.appendChild(item)
- 레이아웃 스타일이 적용될 때
What to do?
- style 속성 변경을 최소화하라
- style 속성 대신 CSS class에 정의하고 className 속성을 변경하라 - 레이아웃 정보를 검색할 때
- Only if reflow is cached
What to do?
- 레이아웃 정보 접근을 최소화 하라
- 한 번 이상 사용될 값은 지역 변수에 저장하라
- DocumentFragment
- 도큐먼트 같은 객체
- 시각적으로 나타나지 않음
- 그것이 만들어진 도큐먼트의 자식으로 간주
- addChild()를 전달할 때 자신보다는 그것의 자식 모두를 추가
var list = document.getElementById("list"); var fragment = document.createDocumentFragment(); for ( var i=0;i<10; i++ ){ var item= document.createElement("li"); fragment.appendChild(item); // No reflow! 새로 생성된 도큐먼트에 붙이므로... } list.appendChild(fragment); // Reflow! 현재 도큐먼트에 붙이므로...
당신의 DOM을 빠르게~!
- HTMLCollection objects 사용을 주의하라
- 도큐먼트에 DOM 조작 수행을 줄여라
- CSS style 대신 CSS class를 사용하라
- 레이아웃 정보에 접근할 때 주의하라
Browsers With Optimizing Engines
- Chrome(V8)
- Safari 4+ (Nitro)
- Firefox 3.5+ (TraceMonkey)
- Opera 10?11? (Carakan)
All use native code generation and JIT compiling to achieve faster JavaScript excution
Summary
- 스코프에 주의하라
- 지역 변수는 당신의 친구들이다
- 함수 실행은 비용이 따른다
- 반복은 조금만 유지하라
- 가능하면 언제나 작업을 피하라
- DOM 상호작용은 최소화하라
- 좋은 브라우저를 사용하고 다른 이들에게도 장려하라
댓글 없음:
댓글 쓰기