{
    "slug": "js_mutation_observer",
    "term": "MutationObserver API",
    "category": "javascript",
    "difficulty": "intermediate",
    "short": "MutationObserver watches DOM tree changes — attribute changes, child additions/removals, text content changes — without polling or event listener on each node.",
    "long": "MutationObserver fires when the observed DOM subtree changes. Config options: childList (child add/remove), attributes (attribute changes), subtree (observe all descendants), characterData (text changes), attributeFilter (specific attributes). Each callback receives MutationRecord[] with type, target, addedNodes, removedNodes, attributeName, oldValue. Use cases: third-party content monitoring, auto-initializing widgets on dynamic HTML, form auto-save on change. Performance: batches mutations and calls callback asynchronously. Alternative to legacy DOMSubtreeModified event.",
    "aliases": [],
    "tags": [
        "javascript",
        "browser-api",
        "dom",
        "observer"
    ],
    "misconception": "MutationObserver fires synchronously for each change — it batches mutations and fires the callback asynchronously after the current script completes.",
    "why_it_matters": "MutationObserver enables reactive patterns for DOM changes without expensive polling loops — essential for progressive enhancement and third-party script integration.",
    "common_mistakes": [
        "Not disconnecting on cleanup — observes forever.",
        "Infinite loops: modifying the DOM inside the callback triggers the observer again.",
        "Observing document.body with subtree:true — very expensive on large pages."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "js_resize_observer",
        "js_intersection_observer",
        "js_dom_manipulation"
    ],
    "prerequisites": [
        "js_dom_manipulation"
    ],
    "refs": [
        "https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver"
    ],
    "bad_code": "// Polling instead of observing:\nsetInterval(() => {\n    if (document.querySelector('.new-content')) {\n        initWidget();\n    }\n}, 100);",
    "good_code": "const observer = new MutationObserver(mutations => {\n    for (const mutation of mutations) {\n        for (const node of mutation.addedNodes) {\n            if (node.classList?.contains('widget')) initWidget(node);\n        }\n    }\n});\nobserver.observe(document.body, { childList: true, subtree: true });\n// Cleanup: observer.disconnect();",
    "quick_fix": "Replace polling (setInterval + querySelector) with MutationObserver for DOM change detection. Disconnect when no longer needed.",
    "severity": "info",
    "effort": "low",
    "created": "2026-03-23",
    "updated": "2026-04-05",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/js_mutation_observer",
        "html_url": "https://codeclaritylab.com/glossary/js_mutation_observer",
        "json_url": "https://codeclaritylab.com/glossary/js_mutation_observer.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[MutationObserver API](https://codeclaritylab.com/glossary/js_mutation_observer) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/js_mutation_observer"
            }
        }
    }
}