window.requestIdleCallback()是浏览器提供的空闲调度机制,用于主线程空闲时执行低优先级任务如预加载JS模块,需检测兼容性并降级为setTimeout或Promise.then,且应结合deadline.timeRemaining()控制执行时机。

window.requestIdleCallback() 是浏览器提供的一种轻量级调度机制,适合在主线程空闲时执行低优先级任务,比如预加载下一页所需的 JS 模块。它不会阻塞渲染或用户交互,但需注意兼容性和使用边界。
确认浏览器支持并设置降级方案
requestIdleCallback 并非所有环境都支持(如 Safari 长期未实现,部分旧版 Chrome 有 Bug)。使用前应检测并 fallback 到 setTimeout 或 Promise.resolve().then():
- 检查
typeof window.requestIdleCallback === 'function' - 不支持时,用
setTimeout(callback, 0)模拟微延迟执行 - 更稳妥的降级可结合
document.visibilityState === 'visible'和performance.now()避免后台标签中误触发
只在真正空闲时发起模块加载
requestIdleCallback 回调接收一个 deadline 对象,通过 deadline.timeRemaining() > 0 判断是否还有空余时间。不要直接调用 import(),而应包装为可中断、可暂停的逻辑:
- 在 deadline 允许范围内调用
import('./next-page.js'),它本身是异步且非阻塞的 - 若 timeRemaining() 不足(例如
- 避免在回调中做大量计算或 DOM 操作,仅做模块加载和缓存(如赋值给
window.__nextPageModule = promise)
结合路由行为与用户意图提升预加载有效性
盲目预加载可能浪费带宽。建议在用户有明确翻页倾向时才触发:
- 监听滚动位置接近底部、鼠标悬停“下一页”按钮 300ms、或
IntersectionObserver监测分页按钮进入视口 - 配合
prefetchLink 标签作为补充(),由浏览器决定是否提前请求 - 加载后暂存 Promise,后续真正跳转时直接 await,避免重复加载
注意模块加载的副作用与清理
动态 import 的模块若含副作用(如自动注册全局事件、修改 document.head),可能在未跳转前就生效。应确保模块设计为“惰性激活”:
- 导出一个初始化函数(如
init()),而非立即执行逻辑 - 预加载只获取模块对象,不调用任何方法;跳转后再显式调用
module.init() - 若用户中途离开当前页,可忽略已加载的 Promise,无需手动卸载(JS 模块无运行时卸载机制)











