zoukankan      html  css  js  c++  java
  • setTimeout和requestAnimationFrame

    在前端做一些持续执行的动画时,一般会通过setTimeOut去实现,其实js还有另一个API和setTimeout功能类似,就是requestAnimationFrame,在说requestAnimationFrame之前项说说setTimeOut和setInterval

    setTimeout 和 setInterval区别

    • setTimeout: 指定延期后调用函数,每次setTimeout计到期到向事件队列推入一个事件
    • setInterval:以指定周期,向事件队列推入一个事件

    setInterval存在的一些问题:

    定时器代码可能在代码再次被添加到队列之前还没有完成执行,结果导致定时器代码连续运行好几次,而之间没有任何停顿。

    而javascript引擎对这个问题的解决是:当使用setInterval()时,仅当没有该定时器的任何其他代码实例时,才将定时器代码添加到队列中。这确保了定时器代码加入到队列中的最小时间间隔为指定间隔。

    但是,这样会导致两个问题:

    • 1、某些间隔被跳过;
    • 2、多个定时器的代码执行之间的间隔可能比预期的小

    使用setTimeout构造轮询模拟定时器

    在前一个定时器代码执行完之前,不会向队列插入新的定时器代码,确保不会有任何缺失的间隔。而且,它可以保证在下一次定时器代码执行之前,至少要等待指定的间隔,避免了连续的运行

    setTimeout(function fn(){
        console.log('我被调用了');
        setTimeout(fn, 100);
    },100);
    

      

    requestAnimationFrame

    requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘。

    显示器有固定的刷新频率(60Hz或75Hz),也就是说,每秒最多只能重绘60次或75次,requestAnimationFrame的基本思想就是与这个刷新频率保持同步,利用这个刷新频率进行页面重绘。

    此外,使用这个API,一旦页面不处于浏览器的当前标签,就会自动停止刷新。这就节省了CPU、GPU和电力。

    requestAnimationFrame是在主线程上完成。这意味着,如果主线程非常繁忙,requestAnimationFrame的动画效果会大打折扣。

    requestAnimationFrame使用一个回调函数作为参数。这个回调函数会在浏览器重绘之前调用

    requestID = window.requestAnimationFrame(callback);
    

     兼容处理

    window.requestAnimFrame = (function(){
        return  window.requestAnimationFrame       ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame    ||
                window.oRequestAnimationFrame      ||
                window.msRequestAnimationFrame     ||
                function( callback ){
                window.setTimeout(callback, 1000 / 60);
            };
    })();
    

    如何使用

    function animation(){
           requestAnimFrame(animation);
       }

    结束动画

    cancelAnimationFrame(animationId);

    requestIdleCallback()

    requestIdleCallback会在每次屏幕刷新时,判断当前帧是否还有多余的时间,如果有,则会调用回调函数

    利用这个特性,我们可以在动画执行的期间,利用每帧的空闲时间来进行数据发送的操作,或者一些优先级比较低的操作,此时不会使影响到动画的性能,或者和requestAnimationFrame搭配,可以实现一些页面性能方面的的优化,

    react 的 fiber 架构也是基于 requestIdleCallback 实现的

    总结

    • 从单线程模型和任务队列出发理解 setTimeout(fn, 0),并不是立即执行。
    • JS 动画用requestAnimationFrame 会比 setInterval 效果更好
    • requestIdleCallback()常用来切割长任务,利用空闲时间执行,避免主线程长时间阻塞。
  • 相关阅读:
    python模块添加
    Python 的列表排序
    python中文处理问题
    排序算法堆排序
    搜索二分搜索
    排序算法(随机)快速排序(递归)
    排序算法计数排序
    OO设计原则总结
    异常控制以及进程调度
    ubuntu12.04 alternate win7 双系统安装
  • 原文地址:https://www.cnblogs.com/liuxiaoru/p/13637983.html
Copyright © 2011-2022 走看看