ProgramingTip

모든 DOM 요소를 반복하는 가장 효율적인 방법?

bestdevel 2020. 11. 28. 10:11
반응형

모든 DOM 요소를 반복하는 가장 효율적인 방법?


불행히도 페이지 DOM 요소를 반복해야하는 가장 모든 기술이 무엇인지 궁금합니다. 나는 아마도 직접 벤치마킹 할 수있는 시간이 있고 누군가가 이미 가지고있는 경험했거나 내가 있기 때문에 몇 가지 옵션이 있기 때문에 필요하지 않습니다.

현재 저는 jQuery를 사용하고 있습니다.

$('body *').each(function(){                                                                                                                            
      var $this = $(this);                                                                                                                                
      //do stuff                                                                                                                                         
});

작동하는 동안 클라이언트에서 약간의 지연이 발생하는 것입니다. 또한 $('body', '*')일반적으로 jQuery보다 빠르다는 사실을 알 수 있습니다. 같은 더 구체적인 jQuery가 경쟁 할 수도 있습니다 .

var items = document.getElementsByTagName("*");
    for (var i = 0; i < items.length; i++) {
        //do stuff
    }

기본 옵션이 더 빠르다고 가정합니다. 내가 고려하지 않은 다른 옵션이 있는지 궁금합니다. 질문으로 노드를 반복하는 재귀 옵션 일 수 있습니다.


한 바닐라 자바 ​​서비스 제공이 가장 빠릅니다. 게시 한 jQuery 솔루션보다 빠 사용 (질문에 대한 내 의견 참조). 루프에서 DOM을 제거하거나 추가하지 않고 순회 순서가 중요하지 않은 경우 역순으로 반복하여 속도를 사용 수도 있습니다.

var items = startElem.getElementsByTagName("*");
for (var i = items.length; i--;) {
    //do stuff
}

편집 :이 벤치 마크를 확인하여 외장 코드를 사용하여 절약 할 수있는 시간을 확인하십시오 : http://jsben.ch/#/Ro9H6


최신 정보 :

$('body *')요소를 반복 하는 데 사용 하지 않습니다 . $('*')JQuery 메서드 를 사용 하면 훨씬 더 빠르게 사용할 수 있습니다 (자세한 내용은 주석 참조).


Plain ol 'JavaScript는 최 면적으로 말하면 훨씬 빠 사용합니다.

테스트 바이올린을 사용하여 JQuery로 13000 개의 요소를 처리하는 데 약 30ms, JavaScript를 사용하여 23000 개의 요소를 처리하는 데 8ms가 필요한 (둘 다 Chrome에서 테스트 됨).

JQuery:      433  elements/ms
JavaScript:  2875 elements/ms

Difference:  664% in favor of plain ol' JavaScript

참고 : 페이지에 엄청나게 많은 양의 요소가없는 것이 큰 차이를 만들지 않을 것입니다. 또한 루프에서 필요한 시간을 맞춰야합니다.

최신 정보 :

다음 은 훨씬 더 많은 요소 (루프 당 약 6500 개)를 고려할 때 된 업데이트 결과입니다. JQuery를 사용하면 1500ms에 약 648000 개, JavaScript를 사용하면 170ms에 658000 개 요소를 얻을 수 있습니다. (둘 다 Chrome에서 테스트 됨) :

JQuery:      432  elements/ms
JavaScript:  3870 elements/ms

Difference:  895% in favor of plain ol' JavaScript

JQuery는 거의 동일하게 유지되는 동안 JavaScript 속도가 빨라진 시청합니다.


일반적으로 좋은 생각은 작동합니다.

function walkDOM(main) {
    var arr = [];
    var loop = function(main) {
        do {
            arr.push(main);
            if(main.hasChildNodes())
                loop(main.firstChild);
        }
        while (main = main.nextSibling);
    }
    loop(main);
    return arr;
}
walkDOM(document.body);

텍스트 노드를 포함하지 않음 :

function walkDOM(main) {
    var arr = [];
    var loop = function(main) {
        do {
            if(main.nodeType == 1)
                arr.push(main);
            if(main.hasChildNodes())
                loop(main.firstChild);
        }
        while (main = main.nextSibling);
    }
    loop(main);
    return arr;
}

편집 됨!


가장 빠른 방법은 document.all(메서드가 아니라 속성이라는 점에 유의하십시오).

나는 jQuery 대신 이것들을 기록하기 위해 Briguy의 대답의 바이올린을 수정했으며 일관되게 더 빠릅니다 (보다 document.getElementsByTagName('*')).

바이올린 .


이것은 주석에 설명 된 문제에 대한 해결책입니다 (실제 질문은 아님). elementFromPoint고정 위치 요소를 배치하려는 영역을 테스트하는 데 사용 하는 것이 훨씬 빠르며 해당 영역의 요소 만 걱정합니다. 예는 다음과 같습니다.

http://jsfiddle.net/pQgwE/4/

기본적으로 찾고있는 요소의 가능한 최소 크기를 설정하고 새로운 고정 위치 요소가 차지하려는 전체 영역을 스캔합니다. 거기에서 발견 된 고유 한 요소 목록을 작성하고 해당 요소의 스타일을 확인하는 것만 걱정하십시오.

이 기술은 찾고있는 요소의 Z- 색인이 가장 높다고 가정합니다 (고정 위치에 대한 합리적인 가정 인 것 같습니다). 이것이 충분하지 않은 경우, 발견 된 후 각 요소를 숨기거나 최소 Z- 색인을 할당하도록 조정하고 더 이상 발견되지 않을 때까지 (확실히) 지점을 다시 테스트 한 다음 복원 할 수 있습니다. 나중에. 이것은 눈에 띄지 않을 정도로 빨리 일어나야합니다.

HTML :

<div style="position:fixed; left: 10px; top: 10px; background-color: #000000; 
    color: #FF0000;">I Am Fixed</div>
<div id="floater">OccupyJSFiddle!<br>for two lines</div>

JS :

var w = $(window).width(), h=$(window).height(),
    minWidth=10,
    minHeight=10, x,y;

var newFloat = $('#floater'), 
    maxHeight = newFloat.height(),
    el, 
    uniqueEls=[],
    i;

for (x=0;x<w;x+=minWidth) {
    for (y=0;y<h&& y<maxHeight;y+=minHeight) {
        el = document.elementFromPoint(x,y);
        if (el && $.inArray(el,uniqueEls)<0) {
            uniqueEls.push(el);
        }
    }
}
// just for the fiddle so you can see the position of the elements 
// before anything's done
// alert("click OK to move the floater into position.");
for (i=0;i<uniqueEls.length;i++) {
    el = $(uniqueEls[i]);
    if (el.css("position")==="fixed") {
        el.css("top",maxHeight+1);
    }
}

newFloat.css({'position': 'fixed',
             'top': 0,
             'left': 0});

참고 URL : https://stackoverflow.com/questions/8747086/most-efficient-way-to-iterate-over-all-dom-elements

반응형