게시글

강좌12 - jQuery - 4년 전 등록

제이쿼리 성능 향상하기(performance)

조회수:
0

안녕하세요. 이번 시간에는 jQuery 성능향상하기 위한 몇 가지 방법을 소개하겠습니다. jQuery는 라이브러리이기 때문에 순수 자바스크립트보다 당연히 성능이 안 좋습니다. 안 그래도 느린데 잘못된 방법으로 코딩을 하면 상황을 더 악화시킬 수 있습니다. 그래서 흔히들 하는 실수와 그에 대한 대처 방법을 소개하겠습니다.

변수 저장

우선 첫 번째로 가장 간단한 건데 많이 놓치고 있는 부분이 있습니다. 제이쿼리로 찾은 객체를 변수에 저장하지 않는 겁니다.

$('#zero').text('저장하지 않으면 매번 함수가 실행됩니다');
$('#zero').append('<button />');
$('#zero').css('color', '#fff');

위와 같이 $('#zero')를 여러 번 쓰는 것을 많이 봤습니다. 하지만 흔히 놓치는 사실이 $()는 함수라는 겁니다. 위의 코드는 매번 함수를 실행합니다. 제이쿼리 분석 강좌를 보면 저 함수는 어마어마하게 복잡해서 실행하는 게 오래 걸립니다. 그래서 변수에 저장해서 단 한 번만 호출하게 하는 겁니다.

var $zero = $('#zero');
$zero.text('이렇게 저장하면 한 번만 실행됩니다');
$zero.append('<button />');
$zero.css('color', '#fff');

마찬가지로 반복문을 돌 때 length도 변수에 저장하는 게 좋습니다.

for (var i = 0; i < array.length; i++) { ... }

위와 같이 하면 반복문을 돌 때마다 array의 length 속성을 조회해야 합니다.

var length = array.length;
for (var i = 0; i < length; i++) { ... }

DocumentFragment 사용

제이쿼리가 왜 이렇게 느릴까요라는 질문에 꼭 나오는 겁니다. 수십, 수백 개의 태그를 동적으로 추가하는 데 documentFragement를 사용하지 않고 그냥 append 했기 때문에 나타나는 현상입니다.

var $zero = $('#zero');
['Aero', 'Bero', 'Cero', 'Dero', ... , 'Zero'].forEach(function(item) {
  $zero.append('<strong>' + item + '</strong>');
});

위와 같이 간단하게 할 수도 있지만 기존에 있는 태그에 append하는 것은 성능에 매우 부담이 갑니다. 또 26번 반복하기 때문에 브라우저는 26번이나 페이지를 새로 그려야 합니다. 만약 반복문의 개수가 수백 수천개라고 생각해보세요. 브라우저가 파업할 겁니다. 이 때 documentFragement가 여러분을 살려줍니다.

var $frag = $(document.createDocumentFragment());
['Aero', 'Bero', 'Cero', 'Dero', ... , 'Zero'].forEach(function(item) {
  $frag.append('<strong>' + item + '</strong>');
});
$('#zero').append($frag);

$frag에 append하는 것은 가상의 메모리 공간에서 일어나는 일이기 때문에 브라우저와는 상관이 없습니다. 마지막에 그 $frag를 원래 태그에 한 번에 append해주는 겁니다. 이렇게 하면 단 한번만 브라우저에 태그가 추가되어 브라우저가 페이지를 새로 그리는 횟수도 한 번뿐입니다.

다른 방법도 있습니다. detach 메소드를 사용하는 겁니다.

var $zero = $('#zero').detach();
['Aero', 'Bero', 'Cero', 'Dero', ... , 'Zero'].forEach(function(item) {
  $zero.append('<strong>' + item + '</strong>');
});
$zero.appendTo($zeroParent);

detach 메소드를 사용하는 순간 원래 있던 #zero 태그는 브라우저에서 떨어져서 메모리 속으로 들어갑니다. 메모리 상에서 append를 해준 후 마지막에 다시 원래 태그의 부모의 자식으로 추가하는 겁니다.

선택자 최적화

제이쿼리 선택자를 사용하는 데 있어 많은 실수를 하곤 합니다. 선택자는 원하는 태그를 선택할 수 있을 정도로만 최소화해서 사용해야합니다. 예를 들면 $('div#zero')는 간단히 $('#zero')로 표현할 수 있습니다. 어차피 id는 단 하나의 태그만 가리키니까요.

또한 id나 class를 사용하는 게 좋습니다. $('div p a')보다는 $('#zero p a')가 훨씬 성능이 좋습니다. 찾길 원하는 태그가 있다면 id나 class를 붙이세요. 

그리고 제이쿼리에서 지원하는 선택자들 :input, :even, :odd 등등은 최대한 피하는 게 좋습니다. 순수 자바스크립트에서 지원하지 않는 만큼, 제이쿼리가 직접 구현해야 하는데요. 이 과정에서 성능이 저하될 수 있습니다.

모두들 위의 팁들을 참고하셔서 브라우저가 파업하지 않도록 도와줍시다. 다음 시간에는 deferred에 대해서 알아보겠습니다!

투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.

댓글

8개의 댓글이 있습니다.
일 년 전
잘 보고 갑니다 ~_~
일 년 전
항상 많이 배웁니다. 감사합니다.
일 년 전
정말 감사합니다~~!
2년 전
감사합니다!!
3년 전
jQuery 를 사용하는 이유가 '코딩의 편의성' 측면에 무게감이 실리는 것인가요?

처리속도가 느리다는 단점은 매우 큰 부분이라 생각되는데 빠르게 코딩해야 하는 현업의 실정상 고객의 사이트 효율성보다는 작업하는 작업자 입장에서의 작업시간 단축과 코딩편의측면이라면 자체 사용 사이트를 만들때엔 순수 자바스크립트로 작업을 하는 것이 맞겠죠?
3년 전
제이쿼리는 일단 코딩하기 매우 편하고 브라우저간 호환 문제를 해결해줍니다. 순수 자바스크립트로 코딩을 추천드리지만 브라우저간 호환 문제가 있을 경우 제이쿼리를 고려해보시는 게 나을겁니다.
3년 전
답변 감사합니다
3년 전
옛날 부터 궁금했는데요. var $zero = $('#zero'); 구문에서 변수에 $를 붙이는 이유가 궁금합니다. 안붙여도 사용이 가능한데 객체라는 의미를 부여해서 유지보수에 용이하기 위한 뜻인지 궁금합니다.
3년 전
그냥 제이쿼리 객체라는 것을 보여주기 위한 겁니다. 안 붙여도 됩니다~
3년 전

오오 빠른 답변 감사합니다
4년 전
Cho 님 덕뷴에 제가 하는 실수들을 많이 줄일 수 있겠내요 감사합니다 ㅎㅎ
4년 전
와 대박... 제가 평소에 별 생각없이 했던것들이 전부 안좋은 코딩습관이었군요... ㅜ.ㅜ
4년 전
사소한 것이 성능을 많이 좌우합니다.