document.createDocumentFragment 또는 document.createElement를 사용해야합니까?


97

나는 한 문서 조각에 대한 읽기 및 DOM 리플 로우 방법 궁금 document.createDocumentFragment에서 차이가 document.createElement나는 DOM 요소를 추가 할 때까지 둘 중이 DOM에 존재하지 않는 것처럼 보이는.

테스트 (아래)를했는데 모두 정확히 같은 시간 (약 95ms)이 걸렸습니다. 아마도 이것은 요소에 적용된 스타일이 없기 때문일 수 있으므로 리플 로우가 없을 수도 있습니다.

어쨌든 아래 예제를 기반으로 DOM에 삽입 할 때 createDocumentFragment대신 사용해야 하는 이유 createElement와 둘 사이의 차이점은 무엇입니까 ?

var htmz = "<ul>";
for (var i = 0; i < 2001; i++) {
    htmz += '<li><a href="#">link ' + i + '</a></li>';
}
htmz += '<ul>';

//createDocumentFragment
console.time('first');
var div = document.createElement("div");
div.innerHTML = htmz;
var fragment = document.createDocumentFragment();
while (div.firstChild) {
    fragment.appendChild(div.firstChild);
}
$('#first').append(fragment);
console.timeEnd('first');

//createElement
console.time('second');
var span = document.createElement("span");
span.innerHTML = htmz;
$('#second').append(span);
console.timeEnd('second');


//jQuery
console.time('third');
$('#third').append(htmz);
console.timeEnd('third');

답변:


98

차이점은 문서 조각을 DOM에 추가 할 때 효과적으로 사라진다는 것입니다. 문서 조각을 삽입 한 DOM의 위치에 문서 조각의 모든 자식 노드가 삽입되고 문서 조각 자체는 삽입되지 않습니다. 조각 자체는 계속 존재하지만 이제는 자식이 없습니다.

이를 통해 동시에 여러 노드를 DOM에 삽입 할 수 있습니다.

var frag = document.createDocumentFragment();
var textNode = frag.appendChild(document.createTextNode("Some text"));
var br = frag.appendChild(document.createElement("br"));
var body = document.body;
body.appendChild(frag);
alert(body.lastChild.tagName); // "BR"
alert(body.lastChild.previousSibling.data); // "Some text"
alert(frag.hasChildNodes()); // false

3
응답 해 주셔서 감사합니다. 동시에 여러 삽입을 허용한다고 말하지만 doc.createElement를 사용하여이를 달성 할 수 있습니다. 유일한 차이점은 먼저 <span> 태그에 요소를 래핑 한 다음 해당 <span>을 DOM에 삽입해야한다는 것입니다. 그래서 createDocumentFragment를 사용해야합니까? 불필요한 요소가 DOM에 삽입되는 것을 방지하려면?
screenm0nkey 2010 년

4
예, 그것은 확실히 그것을 사용하는 한 가지 이유입니다. 또한 문서 조각에는 모든 종류의 노드가 포함될 수 있지만 요소는 포함되지 않을 수 있습니다.
Tim Down

3
실제로 조각은 "사라지지"않습니다. 브라우저는 childNode를 DOM으로 이동합니다. 따라서 조각은 여전히 ​​존재하지만 삽입 후에는 비어 있습니다.
inf3rno

1
@ inf3rno : 따라서 "효과적으로"라는 단어를 사용하고 그 뒤에 나오는 설명은 귀하와 거의 동일합니다. 나는 조각이 자식 노드없이 계속 존재한다고 대답에서 명시 적으로 말 했어야했다는 것을 인정합니다.
Tim Down

1
@TimDown 귀하의 답변에 감사드립니다! 내가 당신의 요점을 맞히면, 성능, 사용 createFragmentcreateElement메모리는 반복적 으로 여러 번 업데이트하는 대신 DOM을 일괄 업데이트 한 것과 거의 동일한 효과가 있습니다. 의 주요 이점은 무료로 추가 할 자식 요소를 선택할 수있는 유연성을 제공한다는 것입니다. 내가 틀렸다면 정정하십시오. createFragment
Xlee

9

요소 생성과 문서 조각 생성의 또 다른 매우 중요한 차이점 :

요소를 생성하여 DOM에 추가하면 해당 요소는 자식뿐 아니라 DOM에도 추가됩니다.

문서 조각을 사용하면 하위 항목 만 추가됩니다.

다음의 경우를보십시오.

var ul = document.getElementById("ul_test");


// First. add a document fragment:


(function() {
  var frag = document.createDocumentFragment();
  
  
  var li = document.createElement("li");
  li.appendChild(document.createTextNode("Document Fragment"));
  frag.appendChild(li);
  
  ul.appendChild(frag);
  console.log(2);
}());

(function() {
  var div = document.createElement("div");
  
  
  var li = document.createElement("li");
  li.appendChild(document.createTextNode("Inside Div"));
   div.appendChild(li);
  
  ul.appendChild(div);
}());
Sample List:
<ul id="ul_test"></ul>

이 잘못된 HTML (공백 추가)이 발생합니다.

<ul id="ul_test">
  <li>Document Fragment</li>
  <div><li>Inside Div</li></div>
</ul>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.