Rev. 2.73

Steven Levithan씨는 자신의 블로그에 흥미로운 내용의 글을 작성했다. "이 포스트는 innerHTML vs. W3C DOM 메서드들의 찬반양론에 관한 것이 아니다."로 시작하는 범상치 않은 이 포스트는 innerHTML의 성능을 끌어올리는 방법을 소개한다. 몇몇 브라우저(주목할 만한 녀석은 파이어폭스)에서는 일반적으로 DOM 메서드를 사용하는 것 보다는 innerHTML이 훨씬 빠르다는 사실을 우리는 잘 알고 있다. RegexPal 을 개발하면서 주된 성능 최적화 작업을 통해 이 사실을 알아냈다. RegexPal은 자바스크립트를 이용하여 문자열을 정규식으로 비교하고 동일한 문자열을 강조하는 테스트 사이트이다.

RegexPal에서는 모든 키다운 이벤트에 문자열 강조를 위한 수전개의 엘리먼트 파괴와 창조 트리거들을 잠제적으로 가지고 있다. 이런 경우 el.innerHTML += str 또는 el.innerHTML = ""만을 가지고는 수천개의 자식 엘리먼트에 접근하여 업데이트하는 과정의 성능을 끌어올리지 못한다. 그래서 아래와같은 replaceHtml 함수를 개발했고 innerHTML과 비교한 성능 측정 페이지를 만들었다. el.innerHTML = newHtml 은 el = replaceHtml(el, newHtml) 처럼 사용할 수 있다.

function replaceHtml(el, html) {
	var oldEl = (typeof el === "string" ? document.getElementById(el) : el);
	/*@cc_on // Pure innerHTML is slightly faster in IE
		oldEl.innerHTML = html;
		return oldEl;
	@*/
	var newEl = oldEl.cloneNode(false);
	newEl.innerHTML = html;
	oldEl.parentNode.replaceChild(newEl, oldEl);
	/* Since we just removed the old element from the DOM, return a reference
	to the new element, which can be used to restore variable references. */
	return newEl;
};

파이어폭스 2.0.0.6에서 태스트한 결과 다음처럼 성능이 향상된 결과를 얻을 수 있었다.

1000 elements...
innerHTML (destroy only): 156ms
innerHTML (create only): 15ms
innerHTML (destroy & create): 172ms
replaceHtml (destroy only): 0ms (faster)
replaceHtml (create only): 15ms (~ same speed)
replaceHtml (destroy & create): 15ms (11.5x faster)

15000 elements...
innerHTML (destroy only): 14703ms
innerHTML (create only): 250ms
innerHTML (destroy & create): 14922ms
replaceHtml (destroy only): 31ms (474.3x faster)
replaceHtml (create only): 250ms (~ same speed)
replaceHtml (destroy & create): 297ms (50.2x faster)

엘리먼트의 수가 많을 수록 속도가 더욱 개선 되는 것을 알 수 있다. 사파리 브라우저의 성능향상률이 가장 좋았으며, 오페라 브라우저는 근소한 차이로 innerHTML 보다는 replaceHtml이 더 빠른 결과를 보여주었다. 특이하게도 오페라 9.23과 IE계열 브라우저에서는 다른 브라우저들과 다르게 더 느린 현상이 나타났다. 그럼에도 불구하고 이 함수를 사용하는 이유는 IE는 전형적으로 innerHTML의 처리가 타 브라우저에 비해 월등히 빠르기 때문에 1.1x 느린 정도의 페널티로 여러 브라우저에서 성능향상을 기대 할 수 있기 때문이다.

주. Prototype에 대응하여 아래처럼 Element 클래스에 등록해 사용하면 $(el).replaceHTML(newHTML)과 같은 형식으로 사용할 수 있다.

Element.addMethods({
  replaceHTML: function(element, html) {
  	var oldEl = element;
  	/*@cc_on // Pure innerHTML is slightly faster in IE
  	oldEl.innerHTML = html;
  	return oldEl;
  	@*/
  	var newEl = oldEl.cloneNode(false);
  	newEl.innerHTML = html;
  	oldEl.parentNode.replaceChild(newEl, oldEl);
  	/* Since we just removed the old element from the DOM, return a reference
  	to the new element, which can be used to restore variable references. */
  	return newEl;
  }
});

Comments

Got something to add? You can just leave a comment.

  • 앗! 좋은 정보 감사합니다. ^^ 한번 적용해 봐야겠네요.. ㅎㅎ

    reply edit

  • 이미 존재하는 노드를 innerHTML로 없애는 것이 부하가 많이 걸리는 군요. 좋은 정보 감사합니다.

    reply edit

  • 좋은 정보네요.

    reply edit

  • 이벤트 이벤트

    몇몇 브라우저(주목할 만한 녀석은 파이어폭스)에서는 일반적으로 DOM 메서드를 사용하는 것 보다는 innerHTML이 훨씬 빠르다는 사실을 우리는 잘 알고 있다.
    --> 이에 대해서는 전제조건이 필요하다.
    같은 브라우저에서 10,000 항목 기준으로 DOM 메소드와 InnerHTML은 거의 차이가 없다. IE와 Firefox 브라우저가 차이가 난다는 표현이 더 현실적이다. 그런데 사용자 관점에서 보면 브라우저 차이를 비교하는 것은 설득력이 떨어진다. 그렇다고 사용자에게 Firefox가 빠르니 이것을 쓰라고 할 수도 없다. 즉, 같은 브라우저에서 어떤 메소드/프로퍼티를 사용할 것인가에 대해 검토를 해야한다.

    아울러 차이가 나는 것도 innerHTML 또는 DOM 메소드 차이보다는 사전에 편집을 위한 방법에서 더 차이가 난다. 예를 들어 +=는 IE에서 쥐약이다. 잘못 작성하면 20초도 더 걸리는 경우도 있다.

    다른 방법으로 DOM Level 3에 발표한 textContent, IE의 innerText를 고려해볼 필요도 있다.
    또, createDocumentFragement() 메소드를 생각할 수도 있으나 FF에서는 1/10정도 속도가 떨어지나, IE에서는 1/10도정도 처리속도가 증가한다. 물론, 이 모든 것은 서버 및 클라이언트 환경에 따라 다르므로 단정지어 말할 수 없는 면이 있다.

    reply edit

  • 출처 : http://firejune.com/ Steven Levithan씨는 자신의 블로그에 흥미로운 내용의 글을 작성했다. "이 포스트는 innerHTML vs. W3C DOM 메서드들의 찬반양론에 관한 것이 아니다."로 시작..

Your Reaction Time!

captcha

avatar