RIC和RAF
- 0
requestIdleCallback()
(RIC) 是一种浏览器 API,它可以在浏览器空闲时执行回调函数。由于它不会阻塞主线程,因此可以用于执行一些后台任务或预加载资源,以避免阻塞用户界面
js
其中,callback 是要运行的函数,options 是一个可选参数对象,可以设置回调函数的超时时间和调度优先级。例如:
js
requestIdleCallback 的返回值是一个 ID,可以用于取消任务:
js
requestIdleCallback()
是一个浏览器 API,可以在主线程空闲时运行回调函数。这使得我们可以在不影响页面流畅性的情况下执行一些较重的操作。在优化 document.addEventListener 监听 scroll 事件时,可以使用 requestIdleCallback() 来推迟处理滚动事件,以减少滚动事件的处理次数。
tsx
ts
requestAnimationFrame
(RAF) 是一种浏览器 API,它可以在浏览器下一次重绘之前执行回调函数。由于它与浏览器的渲染循环同步,因此在使用动画或其他需要频繁更新的元素时非常有用。
js
其中,callback 是要运行的函数。该函数应该负责更新动画或其他页面元素,然后在下一次重新渲染页面之前再次调用 requestAnimationFrame。
js
requestAnimationFrame 的返回值是一个 ID,可以用于取消动画:
js
动画:requestAnimationFrame
是最常见的用例之一。通过在每个动画帧上更新元素的位置或样式,可以创建流畅的动画效果。使用 requestAnimationFrame
可以避免使用 setInterval
或 setTimeout
导致的不同步和性能问题。
游戏:requestAnimationFrame
也非常适合用于游戏开发。在每个游戏循环中使用 requestAnimationFrame
更新游戏状态和元素位置可以确保游戏的流畅度和响应性。
滚动:通过 requestAnimationFrame
更新页面的滚动位置,可以创建平滑的滚动效果,而不会出现卡顿或闪烁的情况。这在单页应用程序或长页面中非常有用。使用 requestAnimationFrame()
仍然可能会导致滚动事件处理函数的频率过高。因此,在实际应用中进行性能测试和调优非常重要,以确保代码可以在各种情况下正常运行
图表:使用 requestAnimationFrame
可以在每个动画帧上更新图表的数据和样式,从而创建动态的、实时的图表效果。
视频播放器:使用 requestAnimationFrame
可以在每个动画帧上更新视频的时间戳和播放状态,从而创建流畅的视频播放效果。
需要注意的是,requestAnimationFrame 的回调函数应该尽可能快地执行完毕,以确保动画的流畅度和响应性。如果需要执行更长时间的任务,可以将它们拆分为多个小任务,并使用 requestIdleCallback 在空闲时运行它们。
requestIdleCallback
和 requestAnimationFrame
都是用于浏览器性能优化的 API,但它们的作用不同。requestIdleCallback
用于在浏览器空闲时运行任务,例如后台工作或预加载资源。requestAnimationFrame
则用于在每次重新渲染页面时更新动画或其他需要频繁更新的元素。
此外,requestIdleCallback
和 requestAnimationFrame
在性能和使用方面也有一些区别:
性能:requestIdleCallback
可以将任务拆分为多个小任务,因此它更适合执行耗时较长的任务。而 requestAnimationFrame
的回调函数应该尽可能快地执行完毕,以确保动画的流畅度。
兼容性:requestIdleCallback
是一个比较新的 API,尚未被所有浏览器支持。而 requestAnimationFrame
已经被广泛支持,可以在大多数现代浏览器中使用。
使用:requestIdleCallback
可以用于执行后台任务或预加载资源,以避免阻塞用户界面。而 requestAnimationFrame
适用于在页面中创建流畅的动画或其他需要频繁更新的元素。
使用建议
在实际项目中,我们可以根据具体场景来选择使用 requestIdleCallback
和 requestAnimationFrame
。一般来说,我们应该优先选择 requestAnimationFrame 来更新动画或其他频繁更新的元素,以确保流畅度和性能。而对于一些后台任务或预加载资源,我们可以使用 requestIdleCallback 来避免阻塞用户界面。
另外,我们还可以结合使用这两个 API,例如在页面中创建复杂的动画时,我们可以使用 requestAnimationFrame
更新动画,同时在动画之外使用 requestIdleCallback
来执行一些后台任务或预加载资源,以提高用户体验。
requestIdleCallback
和 requestAnimationFrame
都是用于浏览器性能优化的 API。requestIdleCallback
可以在浏览器空闲时运行任务,例如后台工作或预加载资源,而 requestAnimationFrame
则用于在每次重新渲染页面时更新动画或其他需要频繁更新的元素。在使用时,我们应该根据具体场景选择合适的 API,同时结合使用它们以提高用户体验。
window.requestIdleCallback(callback[, options]);
window.requestIdleCallback(function() {
console.log('这是一个任务');
}, { timeout: 2000 });
const requestId = window.requestIdleCallback(function() {
console.log('这是一个任务');
});
window.cancelIdleCallback(requestId);
import { useEffect, useRef } from 'react';
function handleScroll() {
// 处理滚动事件
}
function useRequestIdleScroll() {
const tickingRef = useRef(false);
function requestTick() {
if (!tickingRef.current) {
requestIdleCallback(() => {
handleScroll();
tickingRef.current = false;
});
tickingRef.current = true;
}
}
useEffect(() => {
document.addEventListener('scroll', requestTick);
return () => {
document.removeEventListener('scroll', requestTick);
};
}, []);
}
function App() {
useRequestIdleScroll();
// 渲染组件
}
//useRequestIdleScroll.ts
import {useEffect, useRef} from "react";
function useRequestIdleScroll(handler: () => void) {
const tickingRef = useRef(false);
function requestTick() {
if (!tickingRef.current) {
requestIdleCallback(() => {
handler();
tickingRef.current = false;
});
tickingRef.current = true;
}
}
useEffect(() => {
document.addEventListener('scroll', requestTick);
return () => {
document.removeEventListener('scroll', requestTick);
};
}, []);
}
export default useRequestIdleScroll
window.requestAnimationFrame(callback);
function animate() {
// 更新动画
window.requestAnimationFrame(animate);
}
animate();
const animationId = window.requestAnimationFrame(function() {
// 更新动画
});
window.cancelAnimationFrame(animationId);