RIC和RAF

    0

RIC

requestIdleCallback() (RIC) 是一种浏览器 API,它可以在浏览器空闲时执行回调函数。由于它不会阻塞主线程,因此可以用于执行一些后台任务或预加载资源,以避免阻塞用户界面

基本语法

js
window.requestIdleCallback(callback[, options]);

其中,callback 是要运行的函数,options 是一个可选参数对象,可以设置回调函数的超时时间和调度优先级。例如:

js
window.requestIdleCallback(function() { console.log('这是一个任务'); }, { timeout: 2000 });

requestIdleCallback 的返回值是一个 ID,可以用于取消任务:

js
const requestId = window.requestIdleCallback(function() { console.log('这是一个任务'); }); window.cancelIdleCallback(requestId);

requestIdleCallback() 是一个浏览器 API,可以在主线程空闲时运行回调函数。这使得我们可以在不影响页面流畅性的情况下执行一些较重的操作。在优化 document.addEventListener 监听 scroll 事件时,可以使用 requestIdleCallback() 来推迟处理滚动事件,以减少滚动事件的处理次数。

tsx
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(); // 渲染组件 }
ts
//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

RAF

requestAnimationFrame (RAF) 是一种浏览器 API,它可以在浏览器下一次重绘之前执行回调函数。由于它与浏览器的渲染循环同步,因此在使用动画或其他需要频繁更新的元素时非常有用。

js
window.requestAnimationFrame(callback);

其中,callback 是要运行的函数。该函数应该负责更新动画或其他页面元素,然后在下一次重新渲染页面之前再次调用 requestAnimationFrame。

js
function animate() { // 更新动画 window.requestAnimationFrame(animate); } animate();

requestAnimationFrame 的返回值是一个 ID,可以用于取消动画:

js
const animationId = window.requestAnimationFrame(function() { // 更新动画 }); window.cancelAnimationFrame(animationId);

常见场景

  1. 动画:requestAnimationFrame 是最常见的用例之一。通过在每个动画帧上更新元素的位置或样式,可以创建流畅的动画效果。使用 requestAnimationFrame 可以避免使用 setIntervalsetTimeout 导致的不同步和性能问题。

  2. 游戏:requestAnimationFrame 也非常适合用于游戏开发。在每个游戏循环中使用 requestAnimationFrame 更新游戏状态和元素位置可以确保游戏的流畅度和响应性。

  3. 滚动:通过 requestAnimationFrame 更新页面的滚动位置,可以创建平滑的滚动效果,而不会出现卡顿或闪烁的情况。这在单页应用程序或长页面中非常有用。使用 requestAnimationFrame() 仍然可能会导致滚动事件处理函数的频率过高。因此,在实际应用中进行性能测试和调优非常重要,以确保代码可以在各种情况下正常运行

  4. 图表:使用 requestAnimationFrame 可以在每个动画帧上更新图表的数据和样式,从而创建动态的、实时的图表效果。

  5. 视频播放器:使用 requestAnimationFrame 可以在每个动画帧上更新视频的时间戳和播放状态,从而创建流畅的视频播放效果。

需要注意的是,requestAnimationFrame 的回调函数应该尽可能快地执行完毕,以确保动画的流畅度和响应性。如果需要执行更长时间的任务,可以将它们拆分为多个小任务,并使用 requestIdleCallback 在空闲时运行它们。

区别

requestIdleCallbackrequestAnimationFrame 都是用于浏览器性能优化的 API,但它们的作用不同。requestIdleCallback 用于在浏览器空闲时运行任务,例如后台工作或预加载资源。requestAnimationFrame 则用于在每次重新渲染页面时更新动画或其他需要频繁更新的元素。

此外,requestIdleCallbackrequestAnimationFrame 在性能和使用方面也有一些区别:

  • 性能:requestIdleCallback 可以将任务拆分为多个小任务,因此它更适合执行耗时较长的任务。而 requestAnimationFrame 的回调函数应该尽可能快地执行完毕,以确保动画的流畅度。

  • 兼容性:requestIdleCallback 是一个比较新的 API,尚未被所有浏览器支持。而 requestAnimationFrame 已经被广泛支持,可以在大多数现代浏览器中使用。

  • 使用:requestIdleCallback 可以用于执行后台任务或预加载资源,以避免阻塞用户界面。而 requestAnimationFrame 适用于在页面中创建流畅的动画或其他需要频繁更新的元素。

使用建议 在实际项目中,我们可以根据具体场景来选择使用 requestIdleCallbackrequestAnimationFrame。一般来说,我们应该优先选择 requestAnimationFrame 来更新动画或其他频繁更新的元素,以确保流畅度和性能。而对于一些后台任务或预加载资源,我们可以使用 requestIdleCallback 来避免阻塞用户界面。

另外,我们还可以结合使用这两个 API,例如在页面中创建复杂的动画时,我们可以使用 requestAnimationFrame 更新动画,同时在动画之外使用 requestIdleCallback 来执行一些后台任务或预加载资源,以提高用户体验。

总结

requestIdleCallbackrequestAnimationFrame 都是用于浏览器性能优化的 API。requestIdleCallback 可以在浏览器空闲时运行任务,例如后台工作或预加载资源,而 requestAnimationFrame 则用于在每次重新渲染页面时更新动画或其他需要频繁更新的元素。在使用时,我们应该根据具体场景选择合适的 API,同时结合使用它们以提高用户体验。

评论区
共有评论 0
暂无评论