javascript - पूरे DOM में नोड्स का पता लगाने के लिए MutationObserver का प्रदर्शन



html html5 (1)

यह उत्तर बड़े और जटिल पृष्ठों पर लागू होता है।

खासकर यदि पेज लोड होने से पहले एक ऑब्जर्वर जुड़ा हुआ है (जो कि Chrome एक्सटेंशन / WebExtensions / userscripts में document_start / document-start है या सिर्फ <head> अंदर एक सामान्य सिंक्रोनाइज़्ड पेज स्क्रिप्ट में है), लेकिन साथ ही हमवतन डायनामिक रूप से अपडेट किए गए पेज जैसे ब्रांच पर तुलना करें GitHub। यदि पृष्ठ बड़ा और जटिल है ( 1 , 2 ), तो कोई अनधिकृत MutationObserver कॉलबैक पृष्ठ लोड समय में कुछ सेकंड जोड़ सकता है। अधिकांश उदाहरण और मौजूदा पुस्तकालय ऐसे परिदृश्यों के लिए जिम्मेदार नहीं हैं और अच्छे दिखने वाले, उपयोग करने में आसान, लेकिन धीमी गति वाले जेएस कोड की पेशकश करते हैं।

MutationObserver कॉलबैक को एक माइक्रोटैस्क के रूप में निष्पादित किया जाता है जो डोम के आगे के प्रसंस्करण को अवरुद्ध करता है और एक जटिल पृष्ठ पर प्रति सेकंड सैकड़ों या हजार बार फायर किया जा सकता है।

  1. हमेशा devtools प्रोफाइलर का उपयोग करें और पृष्ठ लोडिंग के दौरान खपत किए गए संपूर्ण सीपीयू समय के 1% से कम अपने पर्यवेक्षक कॉलबैक का उपभोग करने का प्रयास करें।

  2. ऑफसेटटॉप और इसी तरह के गुणों के उपयोग से मजबूर सिंक्रोनस लेआउट को ट्रिगर करने से बचें

  3. JQuery जैसे जटिल DOM फ्रेमवर्क / लाइब्रेरी का उपयोग करने से बचें, देशी DOM सामान पसंद करते हैं

  4. जब विशेषताओं का अवलोकन किया जाता है, तो attributeFilter: ['attr1', 'attr2'] उपयोग करें attributeFilter: ['attr1', 'attr2'] .observe() विकल्प।

  5. जब भी संभव हो, प्रत्यक्ष माता-पिता का गैरजरूरी तरीके से निरीक्षण करें ( subtree: false )
    उदाहरण के लिए, यह मूल तत्व के लिए प्रतीक्षा करता है कि document पुनरावर्ती रूप से देखें, सफलता पर पर्यवेक्षक को डिस्कनेक्ट करें, इस कंटेनर तत्व पर एक नया अप्रतिसादी संलग्न करें।

  6. id विशेषता के साथ सिर्फ एक तत्व की प्रतीक्षा करते समय, mutations सरणी (इसमें हजारों प्रविष्टियां हो सकती हैं) को शामिल करने के बजाय insanely fast getElementById उपयोग करें: example ।

  7. यदि वांछित तत्व पृष्ठ पर अपेक्षाकृत दुर्लभ है (उदाहरण के लिए iframe या object ) getElementsByTagName और getElementsByClassName द्वारा लौटाए गए HTMLCollection का उपयोग करें और mutations करने के बजाय उन सभी को रीचेक करें यदि इसके 100 से अधिक तत्व हैं, उदाहरण के लिए।

  8. querySelector और विशेष रूप से बेहद धीमी गति से उपयोग करने से बचें।

  9. यदि querySelectorAll MutationObserver कॉलबैक के अंदर बिल्कुल अपरिहार्य है, तो पहले एक querySelector चेक करें, और यदि सफल हो, तो querySelectorAll साथ आगे बढ़ें। औसतन ऐसे कॉम्बो बहुत तेज होंगे।

  10. यदि नॉन-ब्लीडिंग एज ब्राउजर्स को टारगेट किया जाता है, तो बिल्ट-इन Array विधियों जैसे forEach, फ़िल्टर इत्यादि का उपयोग न करें, जिन्हें कॉलबैक की आवश्यकता होती है क्योंकि Chrome के V8 में ये फ़ंक्शंस हमेशा के लिए क्लासिक की तुलना में महंगे होते हैं for (var i=0 ....) लूप (10-100 गुना धीमा, लेकिन V8 टीम इस पर काम कर रही है [2017]), और MutationObserver कॉलबैक जटिल आधुनिक पृष्ठों के म्यूटेशन के प्रत्येक बैच में दर्जनों, सैकड़ों या हजारों addedNodes साथ प्रति सेकंड 100 बार आग लगा सकता है। ।

    निर्मित बिल्ट-इन की इनलाइनिंग सार्वभौमिक नहीं है, यह आम तौर पर बेंचमार्क जैसे आदिम कोड में होता है। वास्तविक दुनिया में MutationObserver में रुक-रुक कर होने वाली गतिविधियाँ होती हैं (जैसे 1-1000 नोड्स प्रति सेकंड 100 बार रिपोर्ट की जाती हैं) और कॉलबैक कभी भी return x * x रूप में सरल नहीं होते हैं return x * x इसलिए कोड को "हॉट" के रूप में नहीं पहचाना जाता है जो कि पर्याप्त / अनुकूलित हो ।

    लश या इसी तरह के तेज पुस्तकालय द्वारा समर्थित वैकल्पिक कार्यात्मक गणन हालांकि ठीक है। 2018 के रूप में क्रोम और अंतर्निहित V8 मानक सरणी में निर्मित तरीकों को इनलाइन करेगा।

  11. यदि नॉन-ब्लीडिंग एज ब्राउजर्स को टारगेट करते हुए, MutationObserver कॉलबैक के अंदर धीमी ईएस २०१५ लूप्स का उपयोग न करें for (let v of something) जब तक कि for (let v of something) जब तक आप ट्रांसपाइल न करें, ताकि परिणामी कोड लूप के for क्लासिक के रूप में तेजी से चले।

  12. यदि लक्ष्य यह बदलना है कि पृष्ठ कैसा दिखता है और आपके पास यह बताने का एक विश्वसनीय और तेज़ तरीका है कि जोड़े जा रहे तत्व पृष्ठ के दृश्य भाग के बाहर हैं, पर्यवेक्षक को डिस्कनेक्ट करें और setTimeout(fn, 0) माध्यम से एक पूरे पृष्ठ को पुन: जाँच और पुनरावृत्ति के लिए शेड्यूल करें: इसे तब निष्पादित किया जाएगा जब पार्सिंग / लेआउटिंग गतिविधि की प्रारंभिक फट समाप्त हो जाती है और इंजन "साँस" कर सकता है जो एक सेकंड भी ले सकता है। फिर आप उदाहरण के लिए requestAnimationFrame का उपयोग करके पेज को असंगत रूप से संसाधित कर सकते हैं।

सवाल पर वापस:

यह देखने के लिए कि कोई <li> उसमें संलग्न है या नहीं, एक निश्चित कंटेनर ul#my-list देखें।

चूंकि 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});

मुझे पता लगाने के लिए MutationObserver का उपयोग करने में दिलचस्पी है कि क्या HTML पृष्ठ में कहीं एक निश्चित HTML तत्व जोड़ा गया है। उदाहरण के लिए, मैं कहूंगा कि मैं यह पता लगाना चाहता हूं कि डोम में कहीं भी कोई <li> जोड़ा गया है या नहीं।

सभी 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> का जोड़ा जाता है या नहीं।

क्या यह एक समस्या है अगर मैं कम विशिष्ट होना चाहता था, और इस तरह से पूरे HTML शरीर पर <li> लिए देख रहा हूं:

var container = document.querySelector('body');

मुझे पता है कि यह उन बुनियादी उदाहरणों में काम करता है जिन्हें मैंने खुद के लिए सेटअप किया है ... लेकिन क्या ऐसा करने की सलाह नहीं दी गई है? क्या यह खराब प्रदर्शन का परिणाम है? और यदि हां, तो मैं उस प्रदर्शन समस्या का पता कैसे लगाऊं और कैसे मापूं?

मुझे लगा कि शायद एक कारण था कि सभी MutationObserver उदाहरण अपने लक्षित कंटेनर के साथ बहुत विशिष्ट हैं ... लेकिन मुझे यकीन नहीं है।






mutation-observers