无需登录 数据私有 本地保存

isInputPending演示 - 检测用户输入中断长任务

12
0
0
0

⏱️ isInputPending 演示

检测浏览器 navigator.scheduling.isInputPending() API 如何让长任务优雅地让出主线程

API 不可用 API 可用 (Chrome 87+)
浏览器兼容性提示 您的浏览器不支持 navigator.scheduling.isInputPending。演示将使用模拟模式运行(基于时间片检查),您仍可体验优化版与非优化版的差异。建议使用 Chrome 87+ 获得完整体验。

🔴 未优化长任务

阻塞主线程

纯同步循环,不检查用户输入,完全阻塞主线程直到任务完成。

就绪 0%
0
测试点击次数
-
最后响应延迟

🟢 使用 isInputPending 优化

主动让出

循环中定期检查 isInputPending(),检测到用户输入时主动让出主线程。

就绪 0%
0
测试点击
-
响应延迟
0
让出次数
100万 2000万 1亿

📚 常见问题与知识点

什么是 navigator.scheduling.isInputPending()?

navigator.scheduling.isInputPending() 是一个浏览器API,用于检测当前是否有待处理的用户输入事件(如点击、键盘输入、触摸等)。它返回一个布尔值,帮助开发者在长任务中判断是否需要让出主线程以保持界面响应。该API从 Chrome 87 开始支持。

includeContinuous 选项有什么作用?

includeContinuous: true 时,API还会检测连续事件(如 mousemovewheeltouchmovepointermove 等)。默认情况下(false),仅检测离散事件(click、keydown、touchstart等)。对于需要响应拖拽或滚动的场景,建议开启此选项。

isInputPending 和 scheduler.yield() 有什么区别?

isInputPending()检测工具——告诉你是否有待处理输入;scheduler.yield()执行工具——主动让出主线程。两者通常配合使用:先用 isInputPending 检查,如果为true,再调用 yield(或 setTimeout)让出主线程。scheduler.yield() 是更新的API,目前在标准化过程中。

在哪些场景中应该使用 isInputPending?

适合任何可能长时间占用主线程的操作:大量DOM操作、复杂计算、数据处理、Canvas渲染、游戏循环、搜索建议的实时过滤等。在这些场景中定期检查 isInputPending 可以让应用始终保持对用户输入的响应。

浏览器兼容性如何?如何处理不支持的浏览器?

目前主要在 Chrome 87+ 和基于Chromium的浏览器中支持。对于不支持的浏览器,推荐使用时间片策略作为降级方案:使用 performance.now() 跟踪执行时间,每50ms主动让出主线程。本演示在检测到API不可用时也会自动切换到模拟模式。

如何正确地在代码中使用 isInputPending?

典型的用法模式如下:

async function longTaskWithCoop() {
  for (let i = 0; i < totalItems; i++) {
    // 执行一小段工作
    processItem(i);
    
    // 每N次迭代检查一次
    if (i % 500 === 0 && navigator.scheduling?.isInputPending()) {
      // 有待处理输入,让出主线程
      await new Promise(r => setTimeout(r, 0));
    }
  }
}