[Javascript + Performance] How to run a large number of time-consuming tasks and doesn't block rendering
Try option 1: Promise
Promise running in Microtask queue, and rendering should wait until the queue is empty; If you have a large number of time-consuming in microtask, it will also block rendering
function runTask(task) {
Promise.resolve().then(() => {
task()
})
}
So this is NOT a soltuion.
Try option 2: SetTimeout
function runTask(task) {
setTimeout(() => {
task()
}, 0)
}
setTimeout run in Marctasks queue, it will block block the rendering but it will cause rendering to be laggy. Why?
for (;;) {
// pick first task from marcotask queue
// do the task
// check whether it's good time to do the rendering? if yes then render
}
The reason it's not cause blocking rendering, due to everytime it only pick one task.
Laggy is due to different browser might have different handling logic, for example, Chrome might lag but Safari might not.
So setTimeout also doesn't seem to be a good option.
Try option 3: requestAnimationFrame
function runTask(task) {
requestAnimationFrame(() => {
task()
})
}
It will block rendering for sure, becaue before each rendering, browser need to perform task()
which will block rendering.
Try option 4: write custom code to (requestIdleCallback)
function _runTask(task) {
requestIdleCallback(idle => {
if (idle.timeRemaining()>0) {
task()
} else {
_runTask(task)
}
})
}
function runTask(task) {
_runTask(task)
}
The
window.requestIdleCallback()
method queues a function to be called during a browser's idle periods. This enables developers to perform background and low priority work on the main event loop, without impacting latency-critical events such as animation and input response. Functions are generally called in first-in-first-out order; however, callbacks which have atimeout
specified may be called out-of-order if necessary in order to run them before the timeout elapses.
https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
It seems that requestidleCallback
can perform the task well, there is no blocking render.
But there is a problem about browser support, https://caniuse.com/requestidlecallback, as you can see, not all the browsers support this API. If we want to support more browsers, we still need to improve it.
Try option 5: custom code with requestAnimationFrame
function _runTask(task) {
const startTime = Date.now()
requestAnimationFrame(() => {
if (Date.now() - startTime < 16.6) {
task()
} else {
_runTask(task)
}
})
}
function runTask(task) {
_runTask(task)
}
We just need to calculate is there enough time to run the task, then we do it, otherwise wait for next tick.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2023-08-24 [React Typescript] Updating the Global Namespace for an Additional Attribute
2022-08-24 [Typescript] Only Type import or export
2022-08-24 [Typescript] Toolbox: isError
2022-08-24 [Typescript] ts-expect-error
2021-08-24 [Cloud Architect] 1. Design for Availability, Reliability, and Resiliency
2020-08-24 [CSS] Use grid-template to make your CSS Grid declarations more readable
2020-08-24 [Machine Learning Ex2] Linear Regression with Multiple Variables