IntersectionObserver 仅支持被动可见触发,无法主动预测用户行为实现真正预加载;需结合资源发现、优先级调度与缓存策略,否则仅为懒加载。

IntersectionObserver 本身不支持预加载,只负责“可见即触发”;要实现“未见先载”,必须配合资源发现、优先级调度与缓存策略,否则只是懒加载,不是预加载。
为什么 IntersectionObserver 不能直接做预加载
它只在目标元素进入视口(或满足 threshold)时回调,属于被动响应机制。预加载需要主动预测用户行为——比如滚动方向、停留时长、历史路径等,而这些不在 IntersectionObserver 能力范围内。
-
isIntersecting为true才触发,意味着资源已“即将可见”,此时加载已略晚于最优时机 -
rootMargin可设为负值(如'-50px')提前触发,但这是静态偏移,无法动态适配滚动速度或设备性能 - 浏览器对
的预加载支持是独立的,IntersectionObserver 无法替代或控制其发起时机
预加载系统必须拆解的三个模块
真正可落地的“自动预加载”,本质是把 IntersectionObserver 当作一个信号采集器,再叠加两层逻辑:
-
资源发现层:扫描 DOM 中带
data-preload或data-prefetch属性的节点,提取src、href、data-srcset等真实地址,并按类型(image/script/font)分类 -
优先级调度层:基于滚动方向、距离视口顶部的 offset、元素高度、是否在首屏下方 1–2 屏内,动态计算加载权重;例如:
Math.max(0, 1 - (top - window.innerHeight) / (2 * window.innerHeight)) -
执行层:对高权重资源用
fetch()+cache.put()预存,对图片用new Image().src = url触发预加载,对脚本/样式用document.createElement('link')插入rel="preload"
如何避免预加载变成“瞎加载”
没有节制的预加载反而会挤占带宽、触发重复请求、拖慢首屏。关键控制点如下:
- 只对非首屏、且位于当前滚动位置向下
2.5 * window.innerHeight内的元素启用预加载(用entry.boundingClientRect.top判断) - 监听
scroll事件节流(requestIdleCallback或throttle(16ms)),仅在空闲时段更新预加载队列 - 设置全局并发上限(如最多同时预加载 3 个资源),用
Promise.allSettled()控制队列消费 - 检测网络状况:
navigator.onLine和navigator.connection.effectiveType,当为'2g'或'slow-2g'时跳过所有预加载
一个最小可行的预加载触发示例
rootMargin: '0px 0px 200px 0px'










