jQuery에서 하위 요소를 선택하는 가장 빠른 방법은 무엇입니까?


101

내가 아는 한 jQuery 에서 자식 요소를 선택하는 방법에는 여러 가지가 있습니다.

//Store parent in a variable  
var $parent = $("#parent");

방법 1 (범위 사용)

$(".child", $parent).show();

방법 2 (find () 메서드)

$parent.find(".child").show();

방법 3 (직계 자녀 만 해당)

$parent.children(".child").show();

방법 4 (CSS 선택기를 통해) -@spinon에서 제안

$("#parent > .child").show();

방법 5 ( 방법 2와 동일 ) -@Kai에 따름

$("#parent .child").show();

이 문제를 직접 조사 할 수있는 프로파일 링에 익숙하지 않으므로 여러분의 의견을 듣고 싶습니다.

추신 나는 이것이이 질문의 중복 가능성을 이해 하지만 모든 방법을 다루지는 않습니다.


또한 @spinon-직계 자녀에게만 해당됩니까? CSS 사양에 "E 요소의 자식 인 F 요소와 일치"라고 나와 있습니다.
Marko

7
당신은 정말 (당신은 정말 큰 DOM 조작을하는 경우가 아니라면) 빠르다는 것을의 걱정하지 않아도 ... jQuery를 끝내 빨리 ...로 지어진
Reigel

2MB HTML 파일이 있습니다. 방법이나 이유를 묻지 마십시오. :)
Marko

1
예. 첫 번째 수준의 하위 항목 만.
스핀 온

한 가지 더 방법이 있습니다. $ ( "# parent .child"). show (); # 2 방식과 동일합니다. :)
Kai

답변:


95

방법 1방법 2방법 1 이 전달 된 범위를 구문 분석하고에 대한 호출로 변환해야 한다는 점만 다릅니다 $parent.find(".child").show();.

방법 4방법 5는 모두 선택기를 구문 분석 한 다음 각각 : $('#parent').children().filter('.child')및 호출해야합니다 $('#parent').filter('.child').

따라서 방법 3 은 최소한의 작업을 수행하고 가장 직접적인 방법을 사용하여 첫 번째 수준의 자식을 가져 오기 때문에 항상 가장 빠릅니다.

Anurag의 수정 된 속도 테스트를 기반으로합니다 : http://jsfiddle.net/QLV9y/1/

속도 테스트 : (많을수록 좋습니다)

크롬 , 방법 3 최고의 다음 방법 1/2 다음 4/5입니다

여기에 이미지 설명 입력

파이어 폭스 , 방법 3은 여전히 최고의 다음 방법 1/2 다음 4/5입니다

여기에 이미지 설명 입력

오페라 , 방법 3은 여전히 최고의 다음 방법 4/5 다음 1/2

여기에 이미지 설명 입력

IE 8 전반적으로 다른 브라우저보다, 그것은 여전히 방법 3, 1,2,4,5 순서를 다음과 느린 반면,.

여기에 이미지 설명 입력

전반적으로 방법 3 은 직접 호출되기 때문에 사용하기에 가장 좋은 방법이며, 방법 1/2과 달리 자식 요소의 수준을 두 개 이상 탐색 할 필요가 없으며 방법 4/5처럼 구문 분석 할 필요가 없습니다.

그러나이 중 일부에서는 방법 5가 첫 번째 수준이 아닌 모든 어린이를보기 때문에 사과와 오렌지를 비교하고 있음을 명심하십시오.


동일하다는 것은 둘 다 동일한 논리를 사용하여 검색한다는 것을 의미합니까?
Marko

4
방법 1과 2가 동일하다는 뜻이 아닙니까?
Guffa

@Aaron 감사합니다-다른 사람들의 생각을보고 싶습니다. 모두가 동의하면 답변을 수락하겠습니다. Cheers :)
Marko

@JP, $parent.find(".child");명령 으로 변환하기 위해 범위가 전달되고 있음을 인식하는 데 추가 시간이 필요합니다 .
Aaron Harun 2010-07-05

2
@Aaron @Marko-우리는 항상 루트 노드를 컨텍스트로 사용하고 문서가 꽤 크기 때문에 테스트가 약간 왜곡 될 수 있습니다. 그럼에도 불구하고 대부분의 실행에서 1과 2가 서로 20 ops / sec 내에 정렬되는 것을보고 있습니다. 1과 2에 비해 4는 약 100-200 개의 작업이 더 느리고 5는 약 400 개의 작업이 더 느립니다. 이는 자식뿐 아니라 모든 자손을 통과하기 때문에 이해할 수 있습니다. 차트 -tinyurl.com/25p4dhq
Anurag 2010-07-05

13

방법 1

jQuery를 사용하여 더 짧고 빠를 수 없습니다. 이 호출은 $(context).find(selector)( 최적화로 인해 방법 2 )로 직접 내려 가며 getElementById.

방법 2

동일한 작업을 수행하지만 불필요한 내부 함수 호출이 없습니다.

방법 3

using children()은 using 보다 빠르지 만 find()물론 children()루트 요소의 직계 하위 요소 만 찾는 반면 find()모든 하위 요소 (하위 하위 요소 포함)에 대해 반복적으로 하향식 검색합니다.

방법 4

이와 같은 선택기를 사용하면 더 느려 야합니다. 이후 sizzle작업 (jQuery를에서 선택의 엔진 인) 오른쪽에서 왼쪽으로 , 모든 클래스를 일치 .child가 ID '부모'에서 직접 아이 경우 보이는 전에 먼저.

방법 5

올바르게 언급 $(context).find(selector)했듯이이 호출은 jQuery함수 내에서 일부 최적화로 인해 호출을 생성 합니다. 그렇지 않으면 (slower)를 통과 할 수도 있습니다 sizzle engine.


2
var $ parent = $ ( "# parent")에 대해 말하는 것이 아닙니다. 요소에 클래스가있을 때 방법 1이 getElementById를 어떻게 사용할 수 있는지 알 수 없습니다.
Marko

1
나는, 문서는 말한다 방법 1에 동의하고 싶었지만 Internally, selector context is implemented with the .find() method난 당신이 :) 영업의 라벨에 혼동있어 알고, 제발 업데이 트를
Reigel

@Reigel : 사실이 수정되었습니다. @Marko : 구문 분석 #parent은 ID를 나타내며 클래스 인 경우 getElementById분명히 사용하지 않습니다 .
jAndy

10

낡은 포스트이므로 시간에 따라 상황이 바뀝니다. 지금까지 마지막 브라우저 버전에서 몇 가지 테스트를했는데 오해를 피하기 위해 여기에 게시하고 있습니다.

HTML5 및 CSS3 호환 브라우저에서 jQuery 2.1을 사용하면 성능이 변경됩니다.

다음은 테스트 시나리오 및 결과입니다.

function doTest(selectorCallback) {
    var iterations = 100000;

    // Record the starting time, in UTC milliseconds.
    var start = new Date().getTime();

    for (var i = 0; i < iterations; i++) {
        // Execute the selector. The result does not need to be used or assigned
        selectorCallback();
    }

    // Determine how many milliseconds elapsed and return
    return new Date().getTime() - start;
}

function start() {
    jQuery('#stats').html('Testing...');
    var results = '';

    results += "$('#parent .child'): " + doTest(function() { jQuery('#parent .child'); }) + "ms";
    results += "<br/>$('#parent > .child'): " + doTest(function() { jQuery('#parent > .child'); }) + "ms";
    results += "<br/>$('#parent').children('.child'): " + doTest(function() { jQuery('#parent').children('.child'); }) + "ms";
    results += "<br/>$('#parent').find('.child'): " + doTest(function() { jQuery('#parent').find('.child'); }) + "ms";
    $parent = jQuery('#parent');
    results += "<br/>$parent.find('.child'): " + doTest(function() { $parent.find('.child'); }) + "ms";

    jQuery('#stats').html(results);
}
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=7, IE=8, IE=9, chrome=1" />
    <title>HTML5 test</title>
    <script src="//code.jquery.com/jquery-2.1.1.js"></script>
</head>
<body>

<div id="stats"></div>
<button onclick="start()">Test</button>

<div>
    <div id="parent">
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
        <div class="child"></div>
    </div>
</div>

</body>
</html>

따라서 100,000 회 반복하면 다음과 같이 표시됩니다.

JS jQuery 선택기 통계

(포맷을 위해 img로 추가했습니다.)

코드 조각을 직접 실행하여 테스트 할 수 있습니다.)


오! 그럼 .find()좋은 일을하는 것 같습니다 . 계속 사용합니다. :)
앤드류 Surdu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.