代码之家  ›  专栏  ›  技术社区  ›  norixxx

在滚动事件上具有ClearAnimationFrame的RequestAnimationFrame

  •  1
  • norixxx  · 技术社区  · 6 年前

    关于javascript有很多问题 requestAnimationFrame 我已经理解了这个概念,但是有没有性能上的区别? cancelAnimationFrame 在这种情况下?

    // Setup a timer
    var timeout;
    
    // Listen for resize events
    window.addEventListener('scroll', function () {
    
        console.log( 'no debounce' );
    
        // Cancel last animation, if there's one
        if (timeout) {
            window.cancelAnimationFrame(timeout);
        }
    
        // Setup the new requestAnimationFrame()
        timeout = window.requestAnimationFrame(function () {
    
            // Run our scroll functions
            console.log( 'debounced' );
    
        });
    
    }, false);
    

    没有 取消动画框架 :

    // Setup a timer
    var timeout;
    
    // Listen for resize events
    window.addEventListener('scroll', function () {
    
        console.log( 'no debounce' );
    
    
        // Setup the new requestAnimationFrame()
        window.requestAnimationFrame(function () {
    
            // Run our scroll functions
            console.log( 'debounced' );
    
        });
    
    }, false);
    

    我在每个代码上得到相同的结果。

    但我想知道如果不取消动画帧会发生什么。请求的函数是在内存中的某个地方还是其他地方堆积的?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Karen Grigoryan    6 年前

    var isRafLogged = false;
    
    function rafCb(now) {
      if (isRafLogged) {
        console.log('rAF callback executed at: ', now, 'ms');
      }
      requestAnimationFrame(rafCb);
    }
    
    function onWindowScroll() {
      // when in scroll, log aforescheduled rAF() only when in scroll
      isRafLogged = true;
      const now = performance.now();
    
      console.log('scroll callback executed at: ', now, 'ms');
    
      // when out of scroll, stop logging the rAF
      setTimeout(function() {
        isRafLogged = false;
      });
    }
    
    requestAnimationFrame(rafCb);
    
    window.addEventListener('scroll', onWindowScroll);
    html,
    body {
      height: 10000px;
    }
    
    p {
      font-size: 200px;
      writing-mode: vertical-lr;
    }
    <p>.....................................................................................................................................................................................................................................................................................................................................................................</p>

    如果我们安排一个连续的 requestAnimationFrame 循环当我们 scroll 我们会很清楚的看到 rAF 纸卷 正在进行回调 最大一次 VSync event .

    因此回到你的主要问题

    在此上下文中,有无CancelAnimationFrame之间的性能有什么不同?

    一般不会,因为 requestAnimationFrame() 呼叫正在阻塞下一个 纸卷 回调,并且不能比请求的帧回调执行更多的滚动回调,因为它们都以最大每帧渲染次数发生,所以存在1到1的关联。

    但我想知道如果不取消动画帧会发生什么。请求的函数是在内存中的某个地方还是其他地方堆积的?

    所有请求的动画帧回调都堆积在 callbacks ,在最近的垂直同步事件之前刷新。因此,从技术上讲,删除预定回调的唯一方法是 cancelAnimationFrame() 但同样,这与你的案件无关,因为 请求动画帧() 回调与window同时发生 纸卷 回调。

    希望它有意义。