DHTML 속도 향상을 위한 몇 가지 팁
Mark Davis
Microsoft Corporation
요약: 이 기사는 성능에 주로 영향을 주는 일부 DHTML 기능에 대해 설명하고 사용자의 DHTML 페이지 기능을 향상시킬 수 있는 몇 가지 팁을 제시합니다(9페이지/인쇄 페이지 기준).
목차
소개
DHTML 변경 내용 일괄 처리
InnerText 사용
DOM을 사용한 개별 요소 추가
SELECT 요소에서 사용자 옵션 확장
DOM을 사용한 테이블 업데이트
한번 쓰기, 여러 번 사용
지나치게 동적인 속성은 피할 것
데이터 바인딩의 유용성
문서에 Expando 속성을 사용하지 말 것
클래스와 스타일 규칙을 전환하지 말 것
상위 요소를 찾기 전에 텍스트 범위를 축소
기타 자료
소개
Microsoft® Internet Explorer 4.0에 동적 HTML(DHTML)을 도입함으로써 웹 페이지 제작자 및 개발자에게 새로운 프로그래밍 모델 사용을 가능하게 했습니다. 이후 웹 페이지 제작자는 이 강력한 기능을 사용하여 웹 사용자에 대한 다양한 대화식 환경을 활성화함으로써 동적인 컨텐트, 스타일, 위치 지정 등을 제공하게 되었습니다. DHTML의 유연성은 종종 두 가지 이상의 방법을 제공하여 사용자가 원하는 작업을 수행하도록 합니다. 사용자의 요청을 처리하는 Internet Explorer의 HTML 구문 분석 및 렌더링 구성 요소를 이해하면 최상의 작업 방법을 결정할 때 많은 도움이 됩니다. 이 기사는 성능에 주로 영향을 주는 일부 DHTML 기능에 대해 설명하고 사용자의 DHTML 페이지 기능을 향상시킬 수 있는 몇 가지 팁을 제시합니다.
DHTML 변경 내용 일괄 처리
DHTML 웹 페이지 성능을 증가시키는 가장 중요한 방법은 HTML 컨텐트의 변경 내용을 적용하는 방법을 개선하는 것입니다. 웹 페이지를 업데이트하는 여러 가지 방법이 있다는 것을 알아 두어야 합니다. 클라이언트 스크립팅에서부터 웹 페이지 제작자는 여러 블록의 HTML 텍스트를 적용하거나 DHTML 개체 모델(영문 사이트) 또는 W3C 문서 개체 모델(DOM)(영문 사이트)을 사용하여 개별적인 HTML 요소에 액세스 할 수 있습니다. HTML 컨텐트에 변경 내용이 발생할 때마다 Internet Explorer의 HTML 구문 분석 및 렌더링 구성 요소는 해당 페이지의 내부 표시를 재구성하고 문서의 레이아웃 및 흐름을 다시 계산해서 변경된 내용을 표시해야 합니다. 실제 성능은 변경 내용과 웹 페이지 컨텐트에 따라 달라지지만 이러한 작업은 비용이 많이 들게 됩니다. 개별 요소를 액세스하는 대신 HTML 텍스트 블록을 적용하는 경우에는 HTML 파서가 호출되어야 하므로 추가 성능 비용을 초래하게 됩니다. HTML 텍스트를 허용하는 메서드와 속성에는 insertAdjacentHTML(영문 사이트) 및 pasteHTML(영문 사이트) 메서드와 innerHTML(영문 사이트) 및 outerHTML(영문 사이트) 속성이 포함됩니다.
팁 1: 하나의 스크립트 함수에서 HTML 컨텐트를 변경하십시오. 마우스 움직임에 대한 응답처럼 여러 이벤트 처리기를 사용하는 경우 한 위치에서 변경하십시오.
HTML 구문 분석 및 구성 요소 렌더링에 대한 중요한 또 다른 사실은 스크립트 이벤트 처리기 함수가 있는 경우나 setTimeout(영문 사이트)과 같은 메서드가 호출되는 경우와 같이 일단 어떤 스크립트가 제어권을 반환하면 레이아웃을 다시 계산하여 웹 페이지를 표시한다는 것입니다. 이제 Internet Explorer가 변경 내용을 처리하는 방법에 대해 알게 되었으므로 웹 페이지 성능 향상을 시작할 수 있습니다.
팁 2: 여러 업데이트를 수행하는 대신 HTML 문자열 하나를 작성하여 문서를 변경해 보십시오. HTML 컨텐트가 필요하지 않다면 innerText(영문 사이트) 속성 사용을 고려해 보십시오.
다음 예에서 느린 메서드는 innerHTML 속성을 설정할 때마다 HTML 파서를 호출합니다. 성능을 향상시키기 위해 문자열을 작성한 후에 innerHTML 속성이 할당되도록 할 수 있습니다.
느린 메서드:
divUpdate.innerHTML = ""; for ( var i=0; i<100; i++ ) { divUpdate.innerHTML += "<SPAN>This is a slower method! </SPAN>"; }
빠른 메서드:
var str=""; for ( var i=0; i<100; i++ ) { str += "<SPAN>This is faster because it uses a string! </SPAN>"; } divUpdate.innerHTML = str;
자세한 내용은 동적 컨텐트(영문 사이트)를 참조하십시오.
InnerText 사용
DHTML 개체 모델에서 HTML 요소의 텍스트 컨텐트는 innerText(영문 사이트) 속성을 통해 액세스되는 반면 W3C DOM은 별도의 하위 텍스트 노드를 제공합니다. DHTML innerText 속성을 직접 사용하면 DOM의 createTextNode(영문 사이트) 메서드를 호출하는 것 보다 더 빨리 요소 컨텐트를 업데이트할 수 있습니다.
팁 3: innerText 속성을 사용하여 텍스트 컨텐트를 업데이트하십시오.
다음 예는 innerText 속성을 사용하여 성능을 향상시키는 방법을 보여 줍니다.
느린 메서드:
var node; for (var i=0; i<100; i++) { node = document.createElement( "SPAN" ); node.appendChild( document.createTextNode( " Using createTextNode() " ) ); divUpdate.appendChild( node ); }
빠른 메서드:
var node; for (var i=0; i<100; i++) { node = document.createElement( "SPAN" ); node.innerText = " Using innerText property "; divUpdate.appendChild( node ); }
DOM을 사용한 개별 요소 추가
앞서 언급했던 것처럼 HTML 텍스트를 적용하여 액세스하는 방법은 HTML 파서를 호출하므로 이에 따른 성능 손실이 발생합니다. 이러한 이유 때문에 insertAdjacentHTML 메서드에 대한 단일 호출을 수행하는 대신 createElement(영문 사이트)와 insertAdjacentElement(영문 사이트) 메서드를 사용하여 요소를 추가하는 것이 더 빠릅니다.
팁 4: createElement와 insertAdjacentElement 메서드를 호출하는 것이 insertAdjacentHTML 메서드를 호출하는 것보다 빠를 때가 있습니다.
DHTML 업데이트를 일괄 처리하고 insertAdjacentHTML 메서드에 대한 단일 호출을 수행하면 성능을 향상시킬 수는 있지만 DOM에서 직접 요소를 만드는 것이 더 효율적인 경우가 있을 수 있습니다. 그러므로 두 가지 방법을 모두 시도하여 어떤 것이 빠른지 결정하는 것이 좋습니다.
느린 메서드:
for (var i=0; i<100; i++) { divUpdate.insertAdjacentHTML( "beforeEnd", "<SPAN> Uses insertAdjacentHTML() </SPAN>" ); }
빠른 메서드:
var node; for (var i=0; i<100; i++) { node = document.createElement( "SPAN" ); node.innerText = " Uses insertAdjacentElement() "; divUpdate.insertAdjacentElement( "beforeEnd", node ); }
SELECT 요소에서 사용자 옵션 확장
HTML 텍스트 메서드 사용에 관한 이전의 규칙에 대한 예외는 SELECT(영문 사이트) 요소에 많은 OPTION(영문 사이트) 요소를 추가할 때입니다. 여러 옵션에 액세스하려면 createElement 메서드를 호출하는 것보다 innerHTML 속성을 사용하는 것이 더 효율적입나다.
팁 5: SELECT 요소에 많은 옵션을 추가하려면 innerHTML을 사용하십시오.
문자열 연결을 사용하여 SELECT 요소 HTML 텍스트를 작성한 뒤 이 팁을 사용하여 innerHTML 속성을 설정합니다. 옵션이 많은 경우에는 문자열 연결도 성능에 영향을 미칠 수 있습니다. 이런 경우에는 배열을 만들고 Microsoft JScript® join(영문 사이트) 메서드를 호출하여 OPTION 요소 HTML 텍스트의 최종 연결을 수행합니다.
느린 메서드:
var opt; divUpdate.innerHTML = "<SELECT ID='selUpdate'></SELECT>"; for (var i=0; i<1000; i++) { opt = document.createElement( "OPTION" ); selUpdate.options.add( opt ); opt.innerText = "Item " + i; }
빠른 메서드:
var str="<SELECT ID='selUpdate'>"; for (var i=0; i<1000; i++) { str += "<OPTION>Item " + i + "</OPTION>"; } str += "</SELECT>"; divUpdate.innerHTML = str;
더 빠른 메서드:
var arr = new Array(1000); for (var i=0; i<1000; i++) { arr[i] = "<OPTION>Item " + i + "</OPTION>"; } divUpdate.innerHTML = "<SELECT ID='selUpdate'>" + arr.join() + "</SELECT>";
DOM을 사용한 테이블 업데이트
DHTML 테이블 개체 모델에 속해 있는 insertRow(영문 사이트) 및 insertCell(영문 사이트) 메서드를 사용하는 것 보다 DOM 메서드를 사용하여 테이블 행 및 셀을 삽입하는 것이 더 효율적입니다. 특히 크기가 큰 테이블을 만들 때 효율적입니다.
팁 6: 크기가 큰 테이블을 작성하려면 DOM 메서드를 사용하십시오.
느린 메서드:
var row; var cell; for (var i=0; i<100; i++) { row = tblUpdate.insertRow(); for (var j=0; j<10; j++) { cell = row.insertCell(); cell.innerText = "Row " + i + ", Cell " + j; } }
빠른 메서드:
var row; var cell; var tbody = tblUpdate.childNodes[0]; tblUpdate.appendChild( tbody ); for (var i=0; i<100; i++) { row = document.createElement( "TR" ); tbody.appendChild( row ); for (var j=0; j<10; j++) { cell = document.createElement( "TD" ); row.appendChild( cell ); cell.innerText = "Row " + i + ", Cell " + j; } }
한번 쓰기, 여러 번 사용
웹 사이트에서 공통적인 작업을 수행하는 데 스크립트를 사용한다면 둘 이상의 웹 페이지에서 재사용할 수 있도록 이러한 함수를 별도의 파일에 두는 것이 좋습니다. 스크립트 파일을 사용하면 코드 유지 관리를 향상시킬 뿐 아니라 스크립트 파일이 브라우저 캐시에 남아있게 되므로 웹 사이트를 방문하는 동안 사용자 컴퓨터에 한 번만 다운로드하면 됩니다. 개별 파일에도 일반 스타일 규칙을 적용하면 동일한 효과를 얻을 수 있습니다.
Tip 7: 공통 코드를 동작 또는 개별 파일에 두어 스크립트를 재활용하십시오.
스크립트 재활용 기능 향상을 위해 DHTML 첨부 또는 요소 동작(영문 사이트)에 공통 스크립트 작업을 배치하십시오. 동작은 스크립트를 재활용하고 HTML에서 액세스 가능한 구성 요소를 작성하여 사용자 고유의 개체, 메서드, 속성 및 이벤트를 사용한 DHTML 개체 모델 확장을 가능하게 합니다. 동작이 viewlink(영문 사이트) 기능을 사용하지 않는 경우 Internet Explorer 5.5 에서 사용 가능한 lightweight(영문 사이트) 동작 기능을 사용하면 코드 간략화를 더욱 효과적으로 수행할 수 있습니다. 또한 스크립트 코드가 단일 SCRIPT(영문 사이트) 블록 내에 있는 경우 성능을 더욱 향상시킬 수 있습니다.
지나치게 동적인 속성은 피할 것
동적 속성(영문 사이트)을 통하여 웹 페이지 제작자는 속성 값으로 식을 사용할 수 있습니다. 이 식은 실행 시간에 계산되어 속성에 그 결과 값을 적용합니다. 이 기능은 강력합니다. 페이지 스크립트 양을 감소시킬 수 있지만 식이 주기적으로 다시 계산되고 종종 다른 속성 값에 따라 변하기 때문에 성능에 좋지 않은 영향을 줄 수도 있습니다. 위치 지정 속성인 경우에는 특히 그러합니다.
팁 8: 동적 속성 사용을 자제하십시오.
데이터 바인딩의 유용성
데이터 바인딩(영문 사이트)은 웹 페이지의 HTML 요소에 데이터베이스 쿼리 결과 값 또는 XML 데이터 섬(영문 사이트) 컨텐트를 바인딩할 수 있는 강력한 기능입니다. 또한 데이터를 가져오기 위해 서버로 돌아가지 않고도 데이터 정렬 및 필터링 기능 및 다른 데이터 뷰를 제공할 수 있습니다. 회사의 데이터를 선 그래프, 막대 그래프 또는 파이 차트로 나타내고 지점, 제품 또는 판매 기간별로 데이터를 정렬하는 단추가 있는 웹 페이지를 상상해 보십시오. 한 번만 서버를 방문하면 이 모든 기능을 제공할 수 있습니다.
팁 9: 다양한 클라이언트쪽 데이터 뷰를 제공하려면 데이터 바인딩을 사용하십시오.
데이터 바인딩에 대한 자세한 정보는 다음 기사를 참조하십시오.
- 데이터 바인딩 개요(영문 사이트)
- 페이지 데이터 바인딩(영문 사이트)
- 가상적인 데이터 바인딩(영문 사이트)
문서에 Expando 속성을 사용하지 말 것
expando(영문 사이트) 속성은 모든 개체에 추가할 수 있는 임의 속성입니다. 이 속성은 현재 웹 페이지에 정보를 저장하는 경우 유용하며 DHTML 개체 모델을 확장하는 또 다른 방법을 제공합니다. 예를 들어 HTML 요소에 clicked 속성을 할당하여 어느 요소가 클릭되었는지를 알려주는 데 사용할 수 있습니다. 이벤트를 발생시켜 이벤트 처리기 함수에 추가적인 컨텍스트 정보를 제공하는 경우에도 expando 속성을 사용할 수 있습니다. expando 속성을 어떻게 사용하건 document(영문 사이트) 개체에는 이 속성을 설정하지 마십시오. 속성을 설정하면 속성을 액세스할 때 문서가 추가적인 재계산을 수행해야 합니다.
팁10: window(영문 사이트) 개체에 expando 속성을 설정하십시오.
느린 메서드:
for (var i=0; i<1000; i++) { var tmp; window.document.myProperty = "Item "+i; tmp = window.document.myProperty; }
빠른 메서드:
for (var i=0; i<1000; i++) { var tmp; window.myProperty = "Item "+i; tmp = window.myProperty; }
클래스와 스타일 규칙을 전환하지 말 것
클래스와 스타일 규칙을 전환하면 재계산과 전체 문서 레이아웃이 필요하기 때문에 부담이 큰 작업이 될 수 있습니다. 웹 사이트의 컨텐트를 다른 방법으로 보기 위해 스타일시트를 사용하는 경우, 요소의 className(영문 사이트) 속성이나 styleSheet(영문 사이트) 개체를 수정하는 대신 변경할 요소의 style(영문 사이트) 개체를 직접 수정하는 것이 좋습니다.
팁 11: 컨텐트 표시를 변경할 때 style 개체를 직접 수정하십시오.
상위 요소를 찾기 전에 텍스트 범위를 축소
TextRange(영문 사이트) 개체는 사용자가 선택하거나 BODY(영문 사이트)와 같은 HTML 요소에서 가져온 텍스트의 영역입니다. 텍스트 범위의 상위는 parentElement(영문 사이트) 메서드를 호출해 확인합니다. 복잡한 문서 범위는 parentElement 메서드를 호출하기 전에 collapse(영문 사이트) 메서드를 호출하는 것이 효율적입니다.
팁 12: parentElement 메서드를 액세스하기 전에 텍스트 범위를 축소하십시오.
자세한 내용은 TextRange 개체 사용(영문 사이트)을 참조하십시오.
기타 자료
성능에 대한 다른 정보를 보려면 다음 기사를 참조하십시오.
- 최강의 HTML 페이지 구축(영문 사이트)
- 성능을 위한 기타 팁(영문 사이트)
- DHTML 페이지의 성능 향상(영문 사이트)
Mark Davis는 Internet Explorer SDK 설명서 팀의 소프트웨어 디자인 엔지니어입니다. 그는 Internet Explorer 연구에 빠져 있거나 시간이 나면 미국 서북부 지역을 하이킹하는 것이 취미입니다.
'IT > Language' 카테고리의 다른 글
[JAVA] IBM java dump 설정 (0) | 2008.10.28 |
---|---|
[JAVA] jconsole을 이용한 간단한 WAS(jeus) 모니터링(원격 모니터링) (0) | 2008.09.23 |
[JAVA] Runtime클래스의 Process exec(String[] cmdarray) (0) | 2008.09.21 |
[JAVA] java exception (0) | 2008.09.21 |
[JAVA] Map / HashMap / TreeMap / Hashtable (0) | 2008.09.21 |