이번에는 jQuery 코드를 들고 왔습니다성능 최적화방법 요약, jQuery 코드 성능 최적화를 위한 주의사항은 무엇인지, 다음은 실제 사례입니다. 살펴보겠습니다.
1. 요소를 찾으려면 항상 #id를 사용하세요.
jQuery에서 가장 빠른 선택기는 ID 선택기($('#someid'))입니다. 이는 JavaScript의 getElementById( ) 메서드에 직접 매핑되기 때문입니다.
단일 요소 선택
<p id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </p>
성능이 좋지 않은 버튼을 선택하는 방법:
var traffic_button = $('#content .button');
버튼을 직접 선택하는 방법:
var traffic_button = $('#traffic_button');
여러 요소 선택
여러 요소 선택에 대해 이야기하는 동안 실제로 필요한 것은 무엇입니까? DOM 순회 및 루핑이 성능 저하의 원인이라는 것을 알고 있습니다. 성능 손실을 최소화하려면 항상 가장 가까운 상위 ID를 사용하여 찾으십시오.
var traffic_lights = $('#traffic_light input');
2. 클래스 앞에 태그를 사용하세요
jQuery에서 두 번째로 빠른 선택기는 태그 선택기($('head'))입니다. 이는 JavaScript의 getElementsByTagName( ) 메서드에 직접 매핑되기 때문입니다.
<p id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </p>
항상 클래스 앞에 태그 이름을 추가하세요(ID에서 전달하는 것을 기억하세요)
var active_light = $('#traffic_light input.on');
참고: 클래스 선택기는 IE의 jQuery에서 가장 느린 선택기이며 전체 DOM을 반복합니다. 가능하면 사용하지 않도록 하세요. ID 앞에 태그를 추가하지 마세요. 예를 들어, ID가 content인
를 찾기 위해 모든
요소를 반복하므로 속도가 매우 느립니다.
var content = $('p#content');
같은 맥락에서 여러 ID에서 전달되는 것은 중복됩니다.
var traffic_light = $('#content #traffic_light');
3. jQuery 개체 캐싱
jQuery 개체를 변수에 저장하는 습관을 들이세요(위의 예처럼). 예를 들어 다음과 같이 하지 마세요.
$('#traffic_light input.on).bind('click', function(){...}); $('#traffic_light input.on).css('border', '3px dashed yellow'); $('#traffic_light input.on).css('background-color', 'orange'); $('#traffic_light input.on).fadeIn('slow');
대신 작업을 계속하기 전에 jQuery 변수를 로컬 변수에 저장하세요.
var $active_light = $('#traffic_light input.on'); $active_light.bind('click', function(){...}); $active_light.css('border', '3px dashed yellow'); $active_light.css('background-color', 'orange'); $active_light.fadeIn('slow');
팁: $ 접두어를 사용하여 로컬 변수가 jQuery 패키지 세트임을 나타냅니다. 애플리케이션에서 jQuery 선택 작업을 두 번 이상 반복하지 마십시오. 보너스 팁: jQuery 객체 결과의 지연 저장.
프로그램의 다른 곳에서 jQuery 결과 객체를 사용하고 싶거나 함수가 여러 번 실행되는 경우 전역 범위의 객체에 캐시하세요. jQuery 결과 객체를 보관할 전역 컨테이너를 정의하면 이를 다른 함수에서 참조할 수 있습니다.
// Define an object in the global scope (i.e. the window object) window.$my ={ // Initialize all the queries you want to use more than once head : $('head'), traffic_light : $('#traffic_light'), traffic_button : $('#traffic_button')}; function do_something(){ // Now you can reference the stored results and manipulate them var script = document.createElement('script'); $my.head.append(script); // When working inside functions, continue to save jQuery results // to your global container. $my.cool_results = $('#some_ul li'); $my.other_results = $('#some_table td'); // Use the global functions as you would a normal jQuery result $my.other_results.css('border-color', 'red'); $my.traffic_light.css('border-color', 'green'); }
4. 체인 활용도 향상
이전 예제는 다음과 같이 작성할 수도 있습니다.
var $active_light = $('#traffic_light input.on'); $active_light.bind('click', function(){...}) .css('border', '3px dashed yellow') .css('background-color', 'orange') .fadeIn('slow');
이를 통해 코드 작성을 줄이고 JavaScript를 더 가볍게 만들 수 있습니다.
5. 하위 쿼리 사용
jQuery를 사용하면 다른 선택기를 패키지 세트에 연결할 수 있습니다. 상위 개체를 로컬 변수에 저장했기 때문에 향후 선택기의 성능 오버헤드가 줄어듭니다.
<p id="content"> <form method="post" action="/"> <h2>Traffic Light</h2> <ul id="traffic_light"> <li><input type="radio" class="on" name="light" value="red" /> Red</li> <li><input type="radio" class="off" name="light" value="yellow" /> Yellow</li> <li><input type="radio" class="off" name="light" value="green" /> Green</li> </ul> <input class="button" id="traffic_button" type="submit" value="Go" /> </form> </p>
예를 들어 하위 쿼리를 사용하여 나중에 작업을 위해 활성 및 비활성 조명을 캐시할 수 있습니다.
var $traffic_light = $('#traffic_light'), $active_light = $traffic_light.find('input.on'), $inactive_lights = $traffic_light.find('input.off');
팁: 여러 로컬 변수를 쉼표로 구분하여 한 번에 정의하면 일부 바이트를 절약할 수 있습니다.
6. 직접적인 DOM 작업을 제한하세요
DOM 작업의 기본 방법은 메모리에 DOM 구조를 만든 다음 DOM 구조를 업데이트하는 것입니다. 이는 jQuery에 대한 최선의 접근 방식은 아니지만 JavaScript에는 효율적입니다. DOM 구조를 직접 조작하면 성능이 저하됩니다. 예를 들어 요소 목록을 동적으로 생성해야 하는 경우 다음을 수행하지 마세요.
var top_100_list = [...], // assume this has 100 unique strings $mylist = $('#mylist'); // jQuery selects our <ul> element for (var i=0, l=top_100_list.length; i<l; i++){ $mylist.append('<li>' + top_100_list[i] + '</li>'); }
대신 DOM 구조에 요소를 삽입하기 전에 문자열로 요소 집합을 생성하려고 합니다.
Code
var top_100_list = [...], // assume this has 100 unique strings $mylist = $('#mylist'), // jQuery selects our <ul> element top_100_li = ""; // This will store our list items for (var i=0, l=top_100_list.length; i<l; i++){ top_100_li += '<li>' + top_100_list[i] + '</li>'; } $mylist.html(top_100_li);
더 빠른 방법은 DOM 구조에 삽입하기 전에 항상 상위 노드에 많은 요소를 포함해야 한다는 것입니다.
var top_100_list = [...], // assume this has 100 unique strings $mylist = $('#mylist'), // jQuery selects our <ul> element top_100_ul = '<ul id="#mylist">'; // This will store our entire unordered list for (var i=0, l=top_100_list.length; i<l; i++){ top_100_ul += '<li>' + top_100_list[i] + '</li>'; } top_100_ul += '</ul>'; // Close our unordered list $mylist.replaceWith(top_100_ul);
위의 내용을 따랐지만 여전히 성능에 대해 약간 혼란스러운 경우 다음을 참조할 수 있습니다.
* jQuery에서 제공하는 Clone() 메서드를 사용해 보세요. Clone() 메서드는 노드 번호의 복사본을 생성한 다음 이 복사본에 대해 작업을 수행할 수 있습니다.
* DOM DocumentFragments를 사용하세요. jQuery 작성자가 지적했듯이 DOM을 직접 조작하는 것보다 성능이 더 좋습니다(위의 문자열에서 했던 것처럼). 그런 다음 jQuery의 삽입 또는 교체 메서드를 사용하세요. .
7、事件委托(又名:冒泡事件)
除非特别说明,每一个JavaScript事件(如click, mouseover 等)在DOM结构树上都会冒泡到它的父元素上。如果我们想让很多elements(nodes)调用同一个function这是非常有用的。取而代之的是 你可以只对它们的父级绑定一次,而且可以计算出是哪一个节点触发了事件,而不是绑定一个事件监听器到很多节点上这种效率低下的方式。例如,假如我们要开发 一个包含很多input的大型form,当input被选择的时候我们想绑定一个class name。像这样的帮定是效率低下的:
$('#myList li).bind('click', function(){ $(this).addClass('clicked'); // do stuff });
反而,我们应该在父级侦听click事件。
$('#myList).bind('click', function(e){ var target = e.target, // e.target grabs the node that triggered the event. $target = $(target); // wraps the node in a jQuery object if (target.nodeName === 'LI') { $target.addClass('clicked'); // do stuff } });
父节点担当着发报机的工作,可以在触发了事件的目标element上做一些工作。如果你发现自己把一个event listener帮定到很多个element上,那么你这种做法是不正确的。
8、消除查询浪费
虽然jQuery对没有找到任何匹配的elements处理的很好,但是它还是需要花费时间去查找的。如果你的站点有一个全局的JavaScript,你可能会把每个jQuery function都放在 $(document).ready(function(){ // all my glorious code })里。 不要这样做。只去放一些页面上适合用到的function。这样做最有效的方式是你的模板可以完全控制任何时候或者地方执行JavaScript以内联脚 本的方式初始化function。例如,在你的“article”页面模板里,你可能在body标签关闭之前包含以下代码