单页应用中懒加载失效是因为路由切换后新插入的图片未被intersectionobserver监听,需在新节点挂载后立即调用observe(),并配合框架生命周期及时unobserve和disconnect以避免重复监听与内存泄漏。

单页应用(SPA)中路由切换不刷新页面,DOM 动态更新后,原先注册的 IntersectionObserver 不会自动监听新插入的图片——这是懒加载失效的最常见原因。关键不是“重新绑定”,而是“在新节点挂载后及时观察”。
新渲染的图片必须显式调用 observe()
路由切换后,组件或 HTML 片段由框架(如 Vue/React)动态插入,这些新 <img> 元素不会被旧的 Observer 跟踪。
- 不能只在页面初始化时调用一次
observer.observe(img) - 每次有新图片节点插入 DOM 后,必须立即对它调用
observer.observe(img) - 若使用 Vue,推荐在
onMounted或onUpdated钩子中查找并观察;React 中应在useEffect内对 ref 元素调用 - 避免全局遍历所有
img:只观察当前组件/区块内新增的图片,提升性能
防重复观察与内存泄漏
已加载完成的图片若持续被观察,既浪费资源又可能触发多余回调。
- 在回调中判断
entry.isIntersecting === true后,立刻执行img.src = img.dataset.src - 随后调用
observer.unobserve(img),解除对该元素的监听 - 给图片加标记如
data-lazy-loaded="1",可辅助跳过已处理节点 - 组件卸载时(如 Vue 的
onUnmounted、React 的useEffect清理函数),应调用observer.disconnect()释放观察器
结合框架机制做自动接管
手动逐个 observe 容易遗漏,建议封装为可复用逻辑。
- Vue 场景:定义
v-img-lazy指令,在mounted钩子中对绑定的img调用observer.observe(),并在加载完成后unobserve - React 场景:用自定义 Hook(如
useLazyImage),接收 ref 并内部管理 observe/unobserve 生命周期 - 通用方案:监听路由变化事件(如
hashchange或 Vue Router 的afterEach),触发一次局部 DOM 查询 + observe 批量处理
注意 SSR 与 hydration 的衔接
服务端已渲染的图片,在客户端 hydrate 后需恢复懒加载逻辑,否则会直接加载。
- SSR 输出时保留
data-src和占位属性(如src="data:image/gif;base64,..."),不要写真实src - 客户端激活后,先清空已有
src(如有),再统一为带data-src的图片创建 observer - 避免在 hydration 前就运行 observe —— 此时 DOM 尚未就绪,会找不到元素
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











