2017-01-03 10 views
4

:DOM을 만지면 아무 것도 바뀌지 않아도 리플 로우가 발생하고 다시 칠해 집니까? 나는 작은 자바 스크립트 템플릿 엔진 일하고, 나는 모델이 변경 DOM을 업데이트를 처리하는 두 가지 방법이

  1. 확인은 DOM 업데이트가 정말 그 일을하기 전에 필요한 경우입니다. 이것은 불필요한 업데이트를 위험에 빠뜨리지 않는 이점이 있지만 이전 값을 추적하는 데 공간을 낭비합니다.

    if (oldValue !== newValue) { 
        element.textContent = newValue; 
    } 
    
  2. 그냥 해보십시오. 이것은 분명히 간단하지만, 나는 아무 이유없이 다시 칠하기와 리플 로우를 촉발 할까 두려워합니다. 나는 또한 setAttribute, addClassremoveClass를 호출, 플러스 style[prop] = value를 설정하여 DOM을 조작하고

    element.textContent = newValue; 
    

참고.

제 질문은 : 현대적인 브라우저는 실제로 아무것도 변경하지 않고 DOM을 터치하면 실제로 변경된 사항이 없으므로 리플 로우 또는 다시 그리기가 실행되지 않는다는 사실을 알기에 충분히 똑똑합니까?

+2

요즘 브라우저는 매우 똑똑합니다. 변경 사항이없는 경우 리플 로우가 발생하지 않으며 현명한 표시가됩니다. 그리고 그때도 다시 칠하기는 영향을받는 화면 부분에만 적용됩니다. –

+0

* 공간을 낭비하고 있습니다. * 예, 공간은 요즘 프리미엄급이며, 저의 데스크탑에는 32GB의 RAM 만 있습니다. –

+1

@torazaburo 큰 SPA에있는 모든 바운드 값의 사본을 휴대 기기에 저장하는 것은 비용이 많이 들며, 자주 바뀌면 수집해야하는 많은 쓰레기를 만들어 프레임 률을 엉망으로 만듭니다. 큰 효과는 아니지만, 그것을 수행 할 때 제로 포인트가 있다면 여기에서이기는 것이 여전히있을 수 있습니다. – Anders

답변

3

MutationObserver api을 사용하면 DOM 변경 사항을 감지 할 수 있습니다.

다음은 브라우저가 원하는 것을 기반으로 Dom Changed 이벤트를 트리거하는지 확인하는 데 사용할 수있는 예제입니다.

여기에 jquery로 text('...')과 jquery를 사용하지 않는 el.textContent이 있습니다. 크롬 55

  • $(document).ready(function() { 
     
        $('#btn1').click(function() { 
     
        console.log('text changed - jquery'); 
     
        $('#a1').text('text 1'); 
     
        }); 
     
        $('#btn2').click(function() { 
     
        console.log('text changed - textContent'); 
     
        $('#a1')[0].textContent = $('#a1')[0].textContent 
     
        }); 
     
        $('#btn3').click(function() { 
     
        console.log('class changed'); 
     
        $('#a1').attr('class', 'cls' + Math.floor(Math.random() * 10)); 
     
        }); 
     
    }); 
     
    
     
    
     
    var target = $('#a1')[0]; 
     
    
     
    // create an observer instance 
     
    var observer = new MutationObserver(function(mutations) { 
     
        var changed = false; 
     
        mutations.forEach(function(mutation) { 
     
        // You can check the actual changes here 
     
        }); 
     
        console.log('Dom Changed'); 
     
    }); 
     
    
     
    // configuration of the observer: 
     
    var config = { attributes: true, childList: true, characterData: true }; 
     
    
     
    // pass in the target node, as well as the observer options 
     
    observer.observe(target, config);
    .cls1 { 
     
        border: 1px solid red; 
     
    } 
     
    .cls2 { 
     
        border: 1px solid pink; 
     
    } 
     
    .cls3 { 
     
        border: 1px solid cyan; 
     
    } 
     
    .cls4 { 
     
        border: 1px solid darkgreen; 
     
    } 
     
    .cls5 { 
     
        border: 1px solid orange; 
     
    } 
     
    .cls6 { 
     
        border: 1px solid darkred; 
     
    } 
     
    .cls7 { 
     
        border: 1px solid black; 
     
    } 
     
    .cls8 { 
     
        border: 1px solid yellow; 
     
    } 
     
    .cls9 { 
     
        border: 1px solid blue; 
     
    } 
     
    .cls10 { 
     
        border: 1px solid green; 
     
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
     
    <div id="a1" class="cls1">text 1</div> 
     
    <button id="btn1">Change text - jquery (keep original)</button><br /> 
     
    <button id="btn2">Change text - textContent (keep original)</button><br /> 
     
    <button id="btn3">Change class (real change)</button>
    setAttribute() 및 jQuery를 text()Dom Change 이벤트를 트리거.
  • Firefox 50에서 모든 것이 Dom Change 이벤트를 트리거했습니다.
  • Edge 38에서 모든 것이 Dom Change 이벤트를 트리거했습니다.
+1

멋진 답변입니다! 몇 가지 결과가 업데이트되었습니다. 한 생각 : 아니 dom 변경 이벤트 repaint/reflow 의미하지 않습니다. 하지만 DOM 변경 이벤트가 재 페인트/리플 로우를 의미합니까? – Anders

+1

'repaint/reflow'에 관해서는 - 아직 잘 모르겠다. (여전히 검색 중이다.) 그러나 여기 테스트는 시도 할 수있다. - 많은 문자를 가진 요소를 취한다. (1M 문자로 시작할 수있다.),'$ (el) .text ($ (el) .text())'를 사용하십시오. 그것은 jQuery에 의한 것이기 때문에 DOM을 트리거 할 것입니다 - 브라우저가 이것을하기 위해 시간/cpu/scroll 변경을하는지 확인하십시오. – Dekel

+1

FF로 테스트 한 결과 성능 모니터가 다시 칠하기 및 리플 로우시기를 알려줍니다.작은 텍스트 (1K 문자)의 경우 때때로 다시 칠해 지지만 리플 로우는 발생하지 않습니다. 대형 텍스트 (1M 문자)의 경우에는 값 비싼 리플 로우가 발생하고 매번 다시 칠해집니다. – Anders