2. 컴퓨터 이야기/프로그래밍

MS 에서 권장하는 DHTML 자바스크립트 튜닝 12단계

래빗 크리스 2009. 2. 13. 18:18

마이크로소프트 개발자 네트워크에서 옮겨온 내용입니다. 자식들 한국어로는 왜 안 해 놓는건지.
그래도 튜닝 기법이 괘씸(?)해서 옮겨 봅니다. 써니루루 님이 링크를 걸었길래 들렀다가 발견했습니다.
각 단계를 시시콜콜 번역하지는 않았습니다. 번역하면 의미가 달라지는 것같습니다. 다만 설명을 달았습니다.
그리고 유의할 것은 자바스크립트를 튜닝하는 것이지, 웹서버나 네트워크 쪽을 튜닝하는 것이 아니라는 점입니다.
개개인에 따라 PC 성능이 다르고 같은 PC 라도 주인장 나름으로 성능이 다르죠.
그래서, 빠른 PC 에서는 어쩌면 이런 튜닝이 무의미한 것인지도 모릅니다.
하지만, 겁나 느린 PC 를 생각한다면 이런 튜닝이 아주아주 의미가 있습니다.
"이런걸 뭣하러 튜닝해" 하지 마시고, 느린 PC 를 가진 불쌍한(?) 네티즌을 배려해 주심 감사.. :)
그리고, 이건 MS 의 웹브라우저인 인터넷 익스플로러에서 잘 먹히는 코드입니다.
다른 웹브라우저에서는 이런 튜닝이 더 느린 결과를 가져오거나, 아예 안 먹히거나 할 수 있는 부작용(?)이 있습니다.
아무튼, 일단은 읽어 보세요.. ^^. 우리나라 웹브라우저의 9할 이상이 MS 인터넷 익스플로러이니까요.. ㅠㅠ

원문을 보시려면 이곳을 클릭하세요.

미리 설명을 해 두어야 할 것이 있는데.. 우리가 잘 알고 있는 <span> 이나 <a> 같은 것을 태그라고 합니다만,
DHTML 에서는 엘리먼트(element) 또는 노드(node) 라고 이해를 합니다.
DOM 구조에서 각 태그를 노드(node)라는 큰 용기에 담고 다시 엘리먼트로 표시하는 정도라고 이해하면 됩니다.


1. Batch Your DHTML Changes

   예를들어 innerHTML 를 여러번 사용하지 말고 한 두번 적당하게 사용한다는 내용입니다.
   직접 경험해 보시려면 이곳을 클릭하세요. 거의 100~200 배 차이. 대단한 차이다.
   innerHTML 에 값을 넣으면, 무슨 내용을 넣는 것인지 확인하기 위해서 파싱(parsing) 하고,
   어떻게 보여줄 것인지 고민(?)하느라 렌더링(rendering) 하는데..
   innerHTML 문이 여러번 사용되면 그만큼 고민을 많이 해야 한다는 것이죠.
   그런데 innerHTML 여러번 사용할 것을 개발자가 한 번 고민해서 적당하게 조정해 놓으면,
   해당 웹페이지가 빠르게 웹브라우저에서 구현되기 때문에 많은 사람들이 편합니다.
   하나의 자바스크립트 함수 안에서 (머리를 쓰면) 한번만 사용해도 되는 각종 이벤트 핸들러들이나 HTML 내용 변경을
   공연히 번잡하게 여러번 사용하지 않는 것이 튜닝 팁입니다.


요것이 느린 소스. for 문 안에서 루핑되는 횟수만큼 innerHTML 사용.
divUpdate.innerHTML = "";
for ( var i=0; i<100; i++ ){
  divUpdate.innerHTML += "<SPAN>This is a slower method! </SPAN>";
}
요것이 빠른 소스. for 문 안에서는 변수에다 주워 담기만 하다가 for 문 밖에서 innerHTML 을 한번만 사용.
var str="";
for ( var i=0; i<100; i++ ){
  str += "<SPAN>This is faster because it uses a string! </SPAN>";
}
divUpdate.innerHTML = str;



2. Talk to Your innerText

   텍스트를 넣을 때는 appendChild() 라는 무거운 DOM 함수를 사용하지 말고, 보다 가벼운 innerText 속성을 사용한다.
   직접 경험해 보시려면 이곳을 클릭하세요. 동일하거나 두배 정도 차이.
   태그를 넣을 때는 innerHTML 속성을 사용하고, 그냥 텍스트만 넣을 때는 innerText 속성을 사용.
   텍스트는 DOM 에서 아무 의미가 없지만, 태그는 노드 또는 엘리먼트(element) 로 대접받습니다. ^^>
   이번에는 둘다 for 루프를 돌기 때문에 속도는 엇비슷합니다만, appendChild 사용시 최고 두배 느려질 수 있습니다.
   물론 appendChild 를 사용하면 createTextNode 도 사용해야 합니다. 그래서 느려지는 걸까요..?
   첫번째 튜닝 기법에서 설명한 것처럼 for 루프를 사용하지 않도록 코딩을 하는 것이 먼저이겠지만,
   for 루프를 통해 구현해야 할 때가 있습니다. 이번 예제에서는 하나의 노드(node) 안에 텍스트를 for 루프로 넣었지만,
   다른 여러개의 노드 안에 일일이 문자열을 넣어야 한다면 첫번째 튜닝 기법을 못씁니다.
   appendChild DOM 함수를 사용하는 경우 입력하는 것이 텍스트일지라도 (텍스트) 노드를 생성하므로,
   createTextNode 라는 DOM 함수를 동반 호출해야 합니다.

요것이 느린 소스. appendChild 라는 DOM 함수 사용.
var node;
for (var i=0; i<100; i++){
  node = document.createElement( "SPAN" );
  node.appendChild(  document.createTextNode( " Using createTextNode() " ) );
  divUpdate.appendChild( node );
}
요것이 빠른 소스. innerText 라는 속성 사용.
var node;
for (var i=0; i<100; i++){
  node = document.createElement( "SPAN" );
  node.innerText = " Using innerText property ";
  divUpdate.appendChild( node );
}



3. Use the DOM to Add Individual Elements

   같은 DOM 함수라도 createElement/insertAdjacentElement 조합이 insertAdjacentHTML 보다 빠르다.
   직접 경험해 보시려면 이곳을 클릭하세요. 거의 2~3배 이상 차이가 난다.
   insertAdjacentHTML 이 코드도 깔끔하고 속도도 그리 나쁘지 않을 수 있겠지만,
   HTML 태그를 createElement 로 생성하고 (여기서는 SPAN 을 예로 들었다)
   innerText 로 새로 생성한 태그에 값을 넣어,
   insertAdjacentElement 로 생성되는 각 태그들을 이어 붙이는 것이 더 빠르다는 얘기.
   물론 한 두번만 사용된다면 코드가 깔끔한 insertAdjacentHTML 이 더 낫겠다.


요것이 느린 소스. insertAdjacentHTML DHTML 함수 사용.
 for (var i=0; i<100; i++){
  divUpdate.insertAdjacentHTML( "beforeEnd", "<SPAN> Uses insertAdjacentHTML() </SPAN>" );
}
요것이 빠른 소스. createElement 와 insertAdjacentElement DOM 함수 사용.
var node;
for (var i=0; i<100; i++){
  node = document.createElement( "SPAN" );
  node.innerText = " Uses insertAdjacentElement() ";
  divUpdate.insertAdjacentElement( "beforeEnd", node );
}



4. Expand Your Options in a SELECT Element

   select 태그에 option 을 넣는 경우..
   select 를 먼저 생성하고 option 들을 일일이 만들어 넣는 것보다는,
   select 와 option 들을 하나의 문자열에 되담아(+= 연산자) innerHTML 로 한번에 담는 것보다는,
   문자열 배열 변수를 만들어 option 을 담고 배열.join() 하여 innserHTML 로 한번에 담는 것이 낫습니다.
   직접 경험해 보시려면 이곳을 클릭하세요. 거의 20배와 60배 가까이 차이가 난다.
   createElement 가 DOM 함수이기 때문에 innertHTML 이 더 빠를 것이라고 막연히 이해는 되시죠..?
   그런데 select 에는 option 이라는 동일한 태그들이 여럿 들어갑니다.
   이것을 문자열 배열에 되담는 방식(+= 연산자) 보다는
   각각의 option 내용을 일정한 크기의 배열변수에 나누어 담고
   innerHTML 에 select 태그와 배열을 join 함수로 묶어서 문자열로 담는 것이 빠르다는 것이죠.
   혹시 Java 에서 String 으로 정의한 변수에 되담는 방식(+= 연산자)으로 최종 문자열을 만드는 것보다
   StringBuffer 로 정의한 다음 append 메소드로 주워 담아 최종 문자열을 만드는 것이 빠르다는 얘기 들어 보셨죠..?
   못들어 봤으면 할 수 없고.. ^^>
   그렇다면 DB 에서 varchar2 와 char 둘 중에 char 가 더 빠르다는 것은 들어 보셨나요..?
   못들어 봤어도 할 수 없죠. ^^
   아무튼 요점은, 일정하게 동일한 크기에 담았다가 마지막에 크게 합치는 것이,
   크기가 얼마든지 바뀔 수 있는 곳에 계속 합쳐 나가는 것보다 결국 더 빠르게 작업된다는 것이죠.
   이해 안 되심..?
   그러면 물건이 222 개 있는데, 이것들을 하나하나 세는 방식 보다,
   50개씩이든 10개씩이든 따로따로 모아놓고 덩어리씩 세는 방식이 더 빠르다는 것은 이해 되시져..? ㅋㅋ

요것이 느린 소스. innerHTML 로 먼저 외곽을 만들고 내부에 일일이 innerText 사용.
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;
}
요것이 빠른 소스. 문자열에 되담아 맨 마지막에 innerHTML 사용.
var str="<SELECT ID='selUpdate'>";
for (var i=0; i<1000; i++){
  str += "<OPTION>Item " + i + "</OPTION>";
}
str += "</SELECT>";
divUpdate.innerHTML = str;
요것이 더 빠른 소스. 배열에 담았다가 맨 마지막에 innerHML 사용.
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>";



5. Use the DOM to Update Tables

   table 태그를 구성하는 경우는 DOM 함수인 createElement 와 appendChild 를 사용하는 것이 낫다.
   직접 경험해 보시려면 이곳을 클릭하세요. 거의 2~3배 정도 차이가 난다.
   Table 같이 구조화된 태그인 경우는 구조화된 DOM 함수를 쓰는 것이 이득입니다.
   코딩 양은 많지만 속도는 더 빠릅니다. 구현에만 신경쓰지 말고 튜닝을 염두에 두고 코딩하자구요.
 
요것이 느린 소스. insertRow 와 insertCell DHTML 함수 사용.
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;
  }
}
요것이 빠른 소스. createElement 와 appendChild DOM 함수 사용.
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;
  }
}



6. Write Once, Use Many Times

   이번에는 실제 예는 없고 방법론적인 이야기만 하네요.
   일련의 자바스립트들을 파일 단위로 묶고 이것을 외부 자바스크립트 파일로 사용하면,
   브라우저가 캐싱을 하기 때문에 일단 받아 놓은 파일은 더이상 받지 않고 PC 에 있는 것을 바로 사용한다.
   이것은 서버나 네트워크의 영향을 덜 받게 되기 때문에 훨씬 효율적입니다.
   behavior 이용에도 관심을 기울여야 하겠네요.


7. Don't Be Too Dynamic with Your Properties

   대개의 경우 위치 속성과 관련하여 자동으로 재계산 되도록 스크립트를 사용하는 것은 편이성은 있지만,
   해당 속성에 영향을 주는 요소가 변경되면 어떠한 결과를 가져오게 될 지 예측하기가 쉽지 않다.
   사용은 하되 추론 가능한 영향요소를 고려하여 제한적으로 이용하라는 것.
   하지만, 필요하다면 과감히 써야 겠죠.


8. Data Binding is Good for You

   이것도 원론적인 이야기입니다.
   필요시 마다, 그러니까 정렬(sorting)이라든가, 추출(filtering)할 때 DB 와 네트워크를 이용하지 말고,
   이미 받아 놓은 데이타를 가지고 웹브라우저가 DHTML 이용으로 관리할 수 있도록 하라는 것입니다.
   그런데 이것은 조금 문제가 있습니다.
   예를들면, 5만개나 되는 데이타를 모두 받은 다음에 정렬이나 추출을 할 필요가 있을까요..?
   C/S 프로그램이 아니거든요, 웹은. 물론 웹도 일종의 Client-Server 매커니즘이지만 말입니다.
   모르지요, 관리자가 사용하는 프로그램의 웹버전이라면 가능한 얘기일 수도 있습니다.
   일반적인 End 유저인 네티즌의 경우 DB 에서 최소한의 정보만 추출하여 보여지는 것이어야 합니다.
   네트워크 대역을 몇몇 관리자에게만 충분하게 사용하게 하는 구조가 아니거든요, 웹은.. ^^>
   그러니까 데이타 결합 이야기는 웹용 관리자 프로그램일 경우에 적용되는 이야기 입니다.
   이런 프로그램을 하시는 분은 상기 제목을 클릭해서 Data Binding 얘기를 더 읽어 보세요.


9. Keep Your Expando Properties Off the Document

   document 를 경유하지 않는 것이 좋다는 이야기. 이건 석연치 않지만 맞는 말인듯..
   직접 경험해 보시려면 이곳을 클릭하세요. 1.5배 정도 차이가 난다.
   Table 같이 구조화된 태그인 경우는 구조화된 DOM 함수를 쓰는 것이 이득입니다.
   코딩은 더 해야 하지만 속도는 더 빠릅니다. 구현에만 신경쓰지 말고 튜닝을 염두에 두고 코딩하자구요.
 
요것이 느린 소스. window.document 를 사용한 임의 속성.
for (var i=0; i<1000; i++){
  var tmp;
  window.document.myProperty = "Item "+i;
  tmp = window.document.myProperty;
}
요것이 빠른 소스. window 를 사용한 임의 속성.
for (var i=0; i<1000; i++){
  var tmp;
  window.myProperty = "Item "+i;
  tmp = window.myProperty;
}



10. Avoid switching classes and style rules

   스타일 시트나 클래스명 등 한번 고치면 여기저기 수정되어 웹브라우저 일이 많아지는 쪽을 택하지 말고,
   변화가 필요한 태그에 대하여만 스타일을 개별적으로 변경하여 웹브라우저 일을 최소화 하라는 말.


11. Collapse a Text Range Before Finding the Parent

    인터넷 익스플로러에만 한정되는 이야기인 것같은데.. 조금 애매하네요.. ^^>


12. Related Topics

   A. 고성능 HTML 페이지 생성
   B. 다른 튜닝 정보들
   C. 유익한 도구들, DHTML 페이지 성능향상


이상입니다.
한번씩 해 보고 쓸만하다 싶으면 기억해 주시고, 필요없다 싶으면 그랬었나 보다 해 주세요.. ^^>