requestIdleCallback 在移动端为啥不生效?
我在做移动端页面性能优化,想用 requestIdleCallback 来延迟执行一些非关键任务,但在 iOS Safari 和部分安卓浏览器上完全没反应,控制台也没报错。
查了下兼容性,知道有些浏览器不支持,但加了 polyfill 也不行。我这样写的:
if ('requestIdleCallback' in window) {
requestIdleCallback(() => {
console.log('idle callback run');
});
} else {
setTimeout(() => {
console.log('fallback to setTimeout');
}, 0);
}
结果在真机上总是走 setTimeout 分支,连 Chrome DevTools 模拟移动设备时都检测不到这个 API,是我用法有问题吗?
这个方案在移动端兼容性更好,别纠结那 API 了。
问题在于你的检测方式本身没问题,但移动端的情况比较复杂。iOS Safari 一直到 14.5 版本才原生支持 requestIdleCallback,在这之前都是没有的。你用 DevTools 模拟检测不到,说明模拟的是老版本浏览器,这很正常。
关于 polyfill 不生效,常见原因是 polyfill 没有正确加载,或者加载顺序有问题。你检查一下 polyfill 是不是在主脚本之前引入的?
还有个坑很多人不知道:即使是 polyfill,它内部也是用 setTimeout 实现的,而且它的空闲检测逻辑在移动端有时候会判断失误,导致回调根本不会执行。
给你个更稳妥的写法,别纠结 requestIdleCallback 了:
或者如果你想更严谨一点,用 Page Visibility API 配合判断:
说白了,移动端对 requestIdleCallback 的支持本身就一团糟,很多浏览器虽然支持但实现也各种问题。与其跟它较劲,不如直接用 setTimeout,延迟设为 0 或者 1 毫秒就够了,在移动端效果其实差不多,还少一堆兼容性问题。