connectedCallback 仅在元素首次被 appendChild 到 active DOM 树时执行,动态组件切换、innerHTML 替换、未挂载或塞入 Shadow DOM 均不触发;disconnectedCallback 不保证执行,需配合 AbortSignal 和 beforeunload 双保险;推荐节点池化复用而非频繁销毁重建。

connectedCallback 为什么没执行?只认“首次挂载”
动态组件切换时,connectedCallback不触发,不是 bug,是设计如此。它只在元素**首次被 appendChild 到 active DOM 树**时运行,后续 appendChild/removeChild 循环不会重复调用。
常见误判场景:
- 用
innerHTML替换父容器内容 —— 浏览器销毁旧节点、创建新节点,但新节点的connectedCallback只在首次插入时生效,若你反复清空再写入,等于每次都“新建”,但逻辑上你以为是“复用” - 动态
document.createElement('my-card')后没调parent.appendChild(el)—— 节点没进 DOM,回调永远不会来 - 把自定义元素塞进
Shadow DOM内部 —— 它只响应主文档树(document)的连接,不响应 Shadow 树
disconnectedCallback 不可靠,不能当唯一清理入口
它确实是清理定时器、事件监听、AbortController 的主要时机,但浏览器不保证它一定执行。页面刷新、标签页后台冻结、进程崩溃时,这个回调大概率被跳过。
安全做法必须双保险:
立即学习“前端免费学习笔记(深入)”;
- 所有异步操作(如
fetch)都配AbortSignal,并在发起前绑定到组件实例;disconnectedCallback中调abort(),但也要在connectedCallback中检查是否已 abort,避免重复调用 - 全局事件监听(如
window.addEventListener('resize', ...))必须在disconnectedCallback移除,但也要在connectedCallback中先removeEventListener再addEventListener,防止多次挂载导致监听器堆积 - 不要在
disconnectedCallback里做 localStorage 写入等关键持久化操作 —— 应在状态变更时实时存,或用beforeunload补充兜底
DOM 节点复用比销毁重建更稳,尤其在大屏/列表场景
高频切换下频繁 removeChild + createElement 会引发回流抖动、内存碎片、事件重绑开销。大屏项目实测:200 节点每秒滚动更新 10 次,layout 时间飙升 3–5 倍。
推荐用 Map 池化管理:
- 每个节点初始化时必须设唯一
dataset.id,且结构固定(比如子元素 class 名不能动态增删) - 滚出视口或切换隐藏时,不
removeChild,只设el.style.display = 'none'并存入nodePool.set(el.dataset.id, el) - 需要新内容时,先查
nodePool.get(id),存在就复用:恢复显示 + 批量更新textContent、dataset、src等字段,不碰 DOM 结构 - 池中节点一旦被复用,就从 Map 中
delete,避免脏数据残留
attributeChangedCallback 必须显式声明,且只响应 attribute
这个回调不会自动监听任何属性,必须靠 static get observedAttributes() 显式列出。漏写、大小写错、连字符错,都会导致回调静默失效。
注意边界:
-
observedAttributes返回数组,内容必须和 HTML 属性名完全一致:'data-id'就是'data-id',不能写成'datasetid'或'dataId' - 只响应
setAttribute()、removeAttribute()或初始 HTML 解析 ——this.myProp = 'x'是 property 赋值,不触发 - 首次设置时
oldValue为null,初始化逻辑仍得放在connectedCallback里兜底 - 若需 property 与 attribute 同步,得手动在 setter 里调
this.setAttribute('xxx', val)
disconnectedCallback 当作“一定会执行的终局清理”,以及误以为 connectedCallback 会在每次 appendChild 时触发。这两个假设一旦成立,组件就会在滚动、切换、后台切回时悄悄泄漏或失活。



















