본문 바로가기

자바스크립트

[DOM] createDocumentFragment "빈 노드 객체를 생성한다."

반응형

createDocumentFragment

DeocumentFragment 노드는 <li> , <div> , text 등과 같이 DOM 노드에 속한다. 하지만 기존 DOM 노드와는 다르게 분류되어 정의되어 있으며 부모노드가 존재하지 않고, 브라우저 렌더링 시에도 DOM 트리에 포함되지 않는다.

 

즉, 다음과 같이 생성해서 부모 노드의 자식 노드로 추가한다고 해도 막상 브라우저에 렌더링된 요소들을 살펴보면 존재하지 않는다.


createDocumentFragment 의 필요성?

보통 우리가 crateElement 로 만든 새로운 요소들을 부모 노드에 추가하려고 하면, 리플로우와 리페인트 라는 과정을 거친다.

 

이 과정을 단순하게 말하면, 브라우저를 다시 렌더링 하는 것인데, 추가되는 요소가 많을 수록 다시 렌더링 되는 횟수 또한 n번 증가 하기 때문에, 브라우저 성능에 좋지 못한 영향을 미칠 수 있다.

 

그러나, 생성된 요소들을 하나의 컨테이너에 해당하는 노드에 포함시켜서 부모 노드의 자식노드로 추가하게 되면, 재렌더링을 단 한 번만 수행하면 되므로 브라우저 성능 상에도 이점이 있다.

 

이 때 ul 라는 태그에 li 라는 태그를 추가한다고 할 때, 컨테이너 태그로서 docomentFragment 라는 빈 노드를 생성하여 이 노드의 자식 노드로 li 태그를 추가하고, ul 라는 부모 태그에 추가하는 형식으로 사용할 수 있다. 

 

앞서 언급했듯이 docomentFragment노드는  빈 노드로서 브라우저의 html 요소 중 하나로 추가되지 않는다.

따라서 <ul/>  - <documentFragment/> - <li/> 이 아니라 <ul/> - <li/> 형식으로 노드를 추가할 수 있게 된다.

 

즉, 불필요한 태그를 추가하지 않으면서도 브라우저 렌더링 시 성능적 이점을 얻기 위해서 사용할 수 있다.


createDocumentFragment 사용 예시

        //텍스트노드로 사용할 요소의 개수만큼 반복을 돌린다.
        ['a','b','c'].forEach((textEl)=>{
        
            const $ul = document.querySelector('ul');
            const $li = document.createElement('li');   
            const textNode = document.createTextNode(textEl);
            const docFragment = document.createDocumentFragment();

            //li 요소노드의 자식노드로 a,b,c 를 추가한다.
            $li.appendChild(textNode);

            //빈 노드의 자식노드로 li 요소노드를 추가한다.
            docFragment.appendChild($li);

            //ul 부모노드의 자식노드로 빈노드를 추가한다.
            $ul.appendChild(docFragment)
        })


문서조각(documentFragment)은 추가되지 않고 필요한 태그만 추가 되었다.


 

반응형