Skip to content

Latest commit

 

History

History
102 lines (68 loc) · 4.15 KB

DocumentFragment.md

File metadata and controls

102 lines (68 loc) · 4.15 KB

DocumentFragment


repaint와 reflow

브라우저는 생성된 DOM 노드의 레이아웃이 변경될 때, 모든 노드를 다시 계산하고 렌더 트리를 재생성한다. 이러한 과정을 reflow라 하고 reflow가 일어난 후, repaint가 일어난다.

즉, DOM의 노드가 변경될 때 마다 DOM tree라는 자료구조에 접근해야 하기 때문에 DOM의 레이아웃을 변경하는 코드를 작성할 때는 이를 최적화하기 위한 고민이 필요하다.

reflow


function reFlow() {
    var container = document.getElementById('container');

    container.appendChild(document.createTextNode('hello'));
}

위의 코드를 보면 conatiner라는 엘리먼트에 hello라는 TextNode를 추가했다. 이로 인해 DOM 노드의 레이아웃이 바뀌며 reflowrepaint가 일어날 것이다.

repaint


function repaint() {
    var container = document.getElementById('container');

    container.style.backgroundColor = 'black';
    container.style.color = 'white';
}

위의 코드에서는 이전의 코드와 다르게 엘리먼트의 style만 변경했다. 이러한 경우 DOM 노드의 레이아웃은 변경되지 않았고 style속성만 변경되었기 때문에 reflow는 일어나지 않고 repaint만 일어나게 된다.

reflowrepaint가 많아질수록 애플리케이션의 렌더링 성능은 느려지게 되기 때문에 이를 줄일수록 성능을 높일 수 있다.

이에 대한 구체적인 설명은 Repaint와 Reflow를 참고하면 된다.


Why DocumentFragment?

DocumentFragment를 활용하는 것은 reflow를 줄이기 위한 방법 중 하나다.

<body>
	<select id="timer">
    </select>
</body>
function addElements() {
    var target = document.getElementById('timer');
 
    for (var i = 0; i < 24; i++) {
        var option = document.createElement('option');
 
        option.innerText = i;
        target.appendChild(option);
    }
}

위 코드는 0시부터 23시까지의 option엘리먼트를 셀렉트 박스에 추가하는 예제이다.

timer셀렉트박스에 0부터 23까지 반복을 돌려 매번 셀렉트 박스에 엘리먼트를 추가하고 있다. 24번의 DOM 레이아웃 변경이 일어나게 되기 때문에 24번의 reflowrepaint가 각각 일어나게 된다.

DocumentFragment를 활용했을 때의 가장 큰 차이는 DocumentFragment객체는 활성화된 DOM트리의 일부가 아니기 때문에 DocumentFragment객체에서 일어나는 변경사항은 DOM에 영향을 주지 않는다. 즉, reflow를 일으키지 않으며 성능에 큰 영향을 미치지 않게 된다.

function addElements() {
    var target = document.getElementById('timer');
    var docFrag = document.createDocumentFragment();
    for (var i = 0; i < 24; i++) {
        var option = document.createElement('option');
 
        option.innerText = i;
        docFrag.appendChild(option);
    }

    target.appendChild(docFrag.cloneNode(true));
}

위의 코드를 보면 DOM레이아웃을 변경시키는 경우는 timer셀렉트 박스 엘리먼트에 추가할 때 발생한다. 즉, DocumentFragMent객체를 셀렉트 박스 엘리먼트에 추가할 때 1번만 DOM 레이아웃이 변경된다. 따라서 각각 24번의 reflowrepaint가 일어나던 것을 1번씩만 일어나도록 줄일 수 있게 된다.

최신 브라우저의 경우에는 reflow가 발생하지 않도록 엔진을 최적화하기 때문에 DocumentFragment를 통한 성능 향상을 체감할 수 없는 경우가 많다. 그러나 DOM 객체에 대한 다수의 접근을 필요로하는 작업을 수행해야 하는 상황에서는 충분한 성능 향상을 체감할 수 있다.


Reference