DOM 탐색

자바스크립트에서 특정 DOM을 조작할려고 할 때, 우리는 먼저 DOM을 document.getElementById 등의 셀렉터로 찾습니다. 웹(프론트)을 개발하다보면 정말 수도 없이 사용하는 함수입니다. 그런데 이러한 DOM을 찾는 함수도 트리를 탐색하기 때문에 CPU소모가 발생합니다. 여기서는 트리탐색을 최소화하는 몇 가지 방법을 산단하게 살펴보겠습니다.

다음은 트리탐색이 많은 안티패턴입니다.

document.getElementById('chaningDiv').style.backgroundColor = '#EEEEEE';
document.getElementById('chaningDiv').style.fontSize = '10em';
document.getElementById('chaningDiv').style.width = '100px';
document.getElementById('chaningDiv').style.marginLeft = '10px';

이는 다음과 같이 사용하게 좋습니다. 한 번의 DOM을 탐색을 유도하는 것이죠. 스타일요소를 사용하므로 스타일까지 변수에 할당하는것입니다.

var changingDivStyle = document.getElementById('changingDiv').style;
changingDivStyle.backgroundColor = '#EEEEEE';
changingDivStyle.fontSize = '10em';
changingDivStyle.width = '100px';
changingDivStyle.marginLeft = '10px';

메모이제이션 활용

DOM을 탐색하는 것은 클로저 내의 변수를 탐색하는 것보다 더 많은 자원을 소모합니다. 따라서 같은 행동(함수)에 대한 DOM 탐색을 메모이제이션패턴을 사용하여 한 번만 탐색하도록 수정할 수 있습니다.

<form id="myForm">
  <input type="text" name="firstName" id="firstName"/>
  <input type="text" name="middleName" id="middleName"/>
  <input type="text" name="lastName" id="lastName"/>
  <input type="submit" value="submit"/>
</form>
<script>
(function(){
  var memo = {};
  document.getElementById('myForm').onsubmit = function () {
    var inputFirstName = getMemo('firstName'),
        inputMiddleName = getMemo('firstName'),
        inputLastName = getMemo('firstName');
    if(inputFirstName.value === "") {
      alert('First name is manatory');
      inputFirstName.focus();
      return false;
    }

    inputLastName = getMemo('lastName');
    if(inputLastName.value === "") {
      alert('Last name id mandatory');
      inputLastName.focus();
      return false;
    }

    inputMiddelName = getMemo('middleName');
    alert('Hello, ' + inputFirstName.value + " " + 
                      inputMiddleName.value + " " + 
                      inputLastName.value);

  }

  function getMemo(id) {
    memo[id] = memo[id] || document.getElementById(id);
    return memo[id];
  }
}());
</script>

getMemo라는 함수를 정의하고 내부에서 memo객체를 사용하여 메모이제이션패턴을 구현한 예제입니다. getElementById를 id당 한번만 호출하여 DOM트리 탐색시간을 최적화 하였습니다.