전체 DOM에서 노드를 감지하는 MutationObserver의 성능
MutationObserver
특정 HTML 요소가 HTML 페이지의 아무 곳에 나 추가 감지하는 데 사용 하는 데 관심 이 있습니다. 예를 들어 <li>
, DOM의 어느 곳에 나가 추가, 감지하고 싶다고 말씀 드리겠습니다 .
MutationObserver
지금까지 본 모든 예제는 노드가 특정 컨테이너에 추가 여부를 감지합니다. 예를 들면 :
일부 HTML
<body>
...
<ul id='my-list'></ul>
...
</body>
MutationObserver
정의
var container = document.querySelector('ul#my-list');
var observer = new MutationObserver(function(mutations){
// Do something here
});
observer.observe(container, {
childList: true,
attributes: true,
characterData: true,
subtree: true,
attributeOldValue: true,
characterDataOldValue: true
});
이에 따라 예에서는 MutationObserver
매우 많은 컨테이너 ( ul#my-list
)를 감시하여 <li>
'가 추가로 확인 하도록 설정합니다.
구체적 덜 이고 다음과 <li>
같이 전체 HTML 본문 에서 의를 보려면 문제가 있습니까?
var container = document.querySelector('body');
내가 직접 설정하는 기본 예제에서 작동한다는 것을 알고 있습니다.하지만이 작업을 권장하지 않습니다. 이로 인해 성능이 입증 되었습니까? 성능 문제를 어떻게 감지하고 측정 할 수 있습니까?
모든 MutationObserver
예제가 대상 컨테이너에 너무 거기 에 이라는 이유가 존재한다고 확신하지 않습니다.
이 옵션은 복잡한 페이지에 적용됩니다.
페이지로드가 시작되기 전에 관찰자는 (입니다 부착되어 특히 경우 document_start
/ document-start
크롬 확장 / WebExtensions / userscripts 아니면 그냥 일반 동기 페이지 펼쳐 내부에서 <head>
) 더 많은 동적으로 업데이트 된 페이지 예를 들어 분기에 GitHub의. 최적화되지 않은 Mutation Observer ( 1 , 2 ) 페이지가 몇 시간에 초를 추가 할 수 있습니다 . 대부분의 기존의 기존 라이브러리는 사용하기 쉽지만 느린 js 코드를 제공합니다.
MutationObserver는 DOM의 추가 처리를 차단하는 마이크로 실행되고 복잡한 페이지에서 초당 수백 번 실행될 수 있습니다.
항상 devtools 러를 사용하고 관찰자되는 전체 CPU 시간의 1 %를 사용합니다.
offsetTop 및 최적화 속성에 액세스하여 강제 동기 레이아웃 트리거링 방지
jQuery와 같은 복잡한 DOM 프레임 워크 / 라이브러리 사용을 피하고 기본 DOM 항목을 선호합니다.
속성을 관찰 할 때에 서
attributeFilter: ['attr1', 'attr2']
옵션을 사용하십시오.observe()
.가능하면 직계 부모를 비재 귀적으로 관찰하십시오 (
subtree: false
).
예를 들어,document
재귀 적으로 관찰 하여 새로운 부모 요소를 기다렸다가 성공시 관찰자의 연결을 고이 컨테이너 요소에 비 재귀 요소를 연결하는 것이 좋습니다.로 한 요소를 사용할 경우
id
속성, 미친 듯이를 사용하여 빠른getElementById
대신 열거의mutations
배열 (이 항목의 수천 수 있습니다) : 예 .경우 원하는 요소 페이지 (를 들어 상대적 예으로 드문
iframe
또는object
) 라이브 HTMLCollection 의해 반환 된에 사용getElementsByTagName
과getElementsByClassName
그들을 다시 확인 모든 대신 의 열거mutations
가 예를 들어 100 개 이상의 요소가있는 경우.querySelector
특히 매우 느린 사용을 피하십시오querySelectorAll
.querySelectorAll
MutationObserver 내에서 절대적 콜백으로 피할 수없는 경우 먼저querySelector
확인을 수행하고 성공하면querySelectorAll
. 평균적으로 콤보는 훨씬 빠를 것입니다.블리딩이 아닌 엣지 브라우저를 대상으로하는 경우, forEach, 필터 어셈블리 같은 내장 메소드를 사용하지 않고 필요합니다. Chrome의 V8에서는 기존의 함수가 항상 클래식
for (var i=0 ....)
루프에 비해 호출 비용이 많이 들었 기 때문입니다 (10-100 배 더 느림). ,하지만 V8 팀이 작업 중입니다 [2017]). MutationObserver 일련의 복잡한 최신 페이지의 각 변이 배치addedNodes
에서 100 개의 실행될 수 있습니다 .배열 내장의 인라인은 일반적으로 벤치 마크와 기본 코드에서 발생합니다. 실제 세계에서 MutationObserver는 활동이 간헐적으로 급증하며 (예 : 1 ~ 1000 개의 노드가 초당 100 회보고 됨) 더이
return x * x
단순하지 않은 단일 코드가 인라인 / 최적화가 "핫"으로 감지되지 않습니다.lodash 또는 유사한 빠른 라이브러리가 지원하는 대체 기능 열거는 괜찮습니다. 2018 년부터 Chrome 및 기본 V8은 표준 배열 기본 제공 메서드를 인라인합니다.
블리딩이 아닌 엣지 브라우저를 대상으로 하는 경우 결과 코드가 클래식 루프 만큼 빠르게 실행되도록 트랜스 파일하지 않는 한 MutationObserver 콜백 내부 와 같이 느린 ES2015 루프를 사용하지 마십시오 .
for (let v of something)
for
목표가 페이지 모양을 변경하는 것이며 추가되는 요소가 페이지의 보이는 부분 밖에 있음을 알리는 안정적이고 빠른 방법이있는 경우 관찰자를 연결 해제하고
setTimeout(fn, 0)
다음을 통해 전체 페이지 재확인 및 재 처리를 예약하십시오 . 파싱 / 레이아웃 활동의 초기 버스트가 완료되고 엔진은 1 초도 걸릴 수있는 "호흡"할 수 있습니다. 그런 다음 예를 들어 requestAnimationFrame을 사용하여 페이지를 청크 단위로 눈에 띄지 않게 처리 할 수 있습니다.
질문으로 돌아 가기 :
어떤 컨테이너 가 추가
ul#my-list
되었는지 확인하기 위해 매우 특정 컨테이너 를 관찰하십시오<li>
.
li
직계 자식 이므로 추가 된 노드를 찾기 때문에 필요한 유일한 옵션 은 childList: true
위의 조언 # 2를 참조하십시오.
new MutationObserver(function(mutations, observer) {
// Do something here
// Stop observing if needed:
observer.disconnect();
}).observe(document.querySelector('ul#my-list'), {childList: true});
'ProgramingTip' 카테고리의 다른 글
Mongoose에서 하위 문서를 만든 후 채우는 방법은 무엇입니까? (0) | 2020.12.29 |
---|---|
Laravel 5- 모든 템플릿에서 사용 가능한 전역 블레이드 뷰 변수 (0) | 2020.12.29 |
Python : smtplib 모듈을 사용하여 이메일을 보낼 때 "제목"이 표시되지 않음 (0) | 2020.12.28 |
"이름이"rabbit "인 노드가 이미 실행 중"이지만 " 'rabbit'노드에 수 없습니다." (0) | 2020.12.28 |
git push fails :`check out branch : refs / heads / master 업데이트 거부 (0) | 2020.12.28 |