DOM 속도문제 문의
본문
var list = document.getElementById("list");
for(var i = 1; i <= 5000; i++) {
list.innerHTML += `<li>item ${i}</li>`;
}
과
var list = document.getElementById("list");
var html = "";
for(var i = 1; i <= 5000; i++) {
html += `<li>item ${i}</li>`;
}
list.innerHTML = html;
둘중에 어느게 더 빠르며 그 이유는 무언지 알려주세요. !-->!-->
답변 3
당연히 두번째 코드가 더 빠릅니다.
첫번째 코드는 DOM 업데이트사건이 5000번 발생하고, 두번째 코드는 한번만 발생하기때문입니다.
React, VueJS 도 Virtual DOM개념을 받아들여 빈번한 업데이트를 막고 있는것이 바로 이점을 고려한것이 아닐까요?
즉 이러한 virtual DOM 기술을 document.createDocumentFragment() 함수로 아래와 같은 단순한 로직을 출발점으로 합니다.
var list = document.getElementById("list");
var fragment = document.createDocumentFragment();
for(var i = 1; i <= 5000; i++) {
li = document.createElement("li");
li.innerHTML = "item " + i;
fragment.appendChild(li);
i++;
}
list.appendChild(fragment);
이렇게 하면 보다 빠르고 성능이 좋은 코드를 작성할 수 있습니다.
자상한건 https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment 를 참고해주세요.
!-->
두 번째 방법은 일반적으로 첫 번째 방법보다 빠릅니다. 이유는 다음과 같습니다.
첫 번째 접근 방식에서는 각 목록 항목(<li>
)을 목록 요소의 innerHTML에 개별적으로 추가합니다. 즉, 루프가 반복될 때마다 브라우저는 DOM 구조를 업데이트하고 목록을 다시 렌더링하고 잠재적으로 레이아웃 재계산을 트리거해야 합니다. 이것은 비용이 많이 드는 작업이 될 수 있으며, 특히 귀하의 경우(5000회)와 같이 많은 수의 반복을 처리할 때 그렇습니다.
두 번째 방법에서는 +=
연산자를 사용하여 목록 항목을 연결하여 문자열(html
)을 만듭니다. 루프가 완료된 후 생성된 HTML 문자열을 단일 작업으로 목록 요소의 innerHTML에 할당합니다. 이 접근 방식은 DOM 업데이트 및 다시 렌더링 횟수를 최소화하여 성능을 향상시킵니다.
DOM 업데이트 수를 줄이고 문자열 연결을 활용함으로써 두 번째 접근 방식은 DOM을 반복적으로 수정하는 것과 관련된 오버헤드를 방지하여 많은 수의 목록 항목을 생성하는 데 더 빠르고 효율적입니다.
따라서 많은 수의 요소를 동적으로 생성해야 하는 경우 일반적으로 두 번째 방법이 권장됩니다.
간략이 설명 드리면 두번째 방법의 경우 문자열에 HTML 코드를 담아 한번만 실행하는하는 것이고
첫번째 방법은 반복문이 돌때마다 실행되는 방식이라서 그렇습니다.!