【问题标题】:Profile specific animation CPU配置文件特定动画 CPU
【发布时间】:2016-08-06 08:18:16
【问题描述】:

情况和问题
我的网站中有多个动画(css 和 javascript/jQuery),有时它会使我的网站卡顿。

我的问题
如何查看特定动画(CSS、JavaScript 和 jQuery)在运行时和执行时使用了多少 CPU

我知道如何查看整个站点的 CPU 使用情况,但不能查看特定动画。

【问题讨论】:

  • 你看过 Chrome DevTools 吗?请参阅developer.chrome.com/devtools/docs/timelinestackoverflow.com/a/16752638/827168 了解更多信息
  • @pomeh 是的,我做到了,但我看不到哪个 CSS 动画占用了大量 CPU
  • 我之前尝试过这个,但随后通过禁用三个动画中的两个,三次,继续分析网站。
  • CSS 动画使用 GPU 周期,而不是 CPU 周期。常规的 JavaScript 分析器应该为您提供执行时间和 CPU 使用率,但由于 CSS 动画的工作机制完全不同,因此这些分析器不是您所需要的。 CSS 动画的全部意义在于它们是硬件加速的,这意味着 CPU 不是它们背后的主要驱动力。
  • 使用操作系统任务表;它不关心原因是什么或工作是如何进行的,只关心工作的多少。

标签: javascript jquery html css cpu


【解决方案1】:

点击 F12,转到配置文件,点击开始。重新加载页面。

等到您的页面重新加载,然后单击停止。

点击您的个人资料并查看结果 (Y)

【讨论】:

    【解决方案2】:

    也许你可以在 Firefox 中使用 console.profile()。 http://www.stoimen.com/blog/2010/02/02/profiling-javascript-with-firebug-console-profile-console-time/

    console.profile()放在要测量的函数之前,将console.profileEnd()放在方法之后。

    <html>
      <body>
        <script>
          myFunc = function() {
            var a = [];
          }             
    
          console.profile();
          myFunc();
          console.profileEnd();
        </script>
      </body>
    </html>
    

    https://developer.chrome.com/devtools/docs/console-api 在这里您可以找到更多的调试方法。

    编辑:我刚刚找到另一个站点,其中包含有关 firebug 扩展的有用信息: https://getfirebug.com/wiki/index.php/Console.profile

    【讨论】:

    • 我给了你赏金,因为你最接近回答我的问题。
    • 谢谢。我只是找不到如何检查 css 动画的 cpu 使用情况。如果我找到它,我也会在这里发布。
    【解决方案3】:

    前言:这不是一个“完整”的答案,而是我能在合理时间内提出的最佳答案。 发布我的结果似乎是一种耻辱,即使它们不是一个完美的答案......

    它也只涵盖jQuery.animate;我没有研究 CSS 动画。


    至少对于 jQuery,这很困难;它不像浏览器“知道” 一个 jQuery 动画。实际上,jQuery 所做的只是安排一个函数以 setTimeout() 运行 n 次 或setInterval(),每个函数调用都会将元素移动几个像素(或稍微更改一些其他内容),从而产生平滑动画的错觉。

    您的浏览器必须以某种方式跟踪属于哪个函数调用 到哪个动画。因为这些是匿名函数,所以这不是真的 容易......可以使用某种特殊的调试语句,但AFAIK没有 浏览器实现了这样的功能。

    我们可以做的是测量 jQuery.animatestep回调:

    为每个动画元素的每个动画属性调用的函数。 此函数提供了修改 Tween 对象以更改 设置之前的属性值。

    这最多只能给你一个近似值。但也许这很好 足够的;我创建了一个示例(见下文),它在我的 系统:

    "a: 52 updates; 26 upd/s"
    "b: 27 updates; 54 upd/s"
    "c: 1080 updates; 360 upd/s"
    

    您的系统可能会有所不同,但建议:

    • a 是最便宜的;
    • b 稍微贵一点,但实际上也很便宜
    • cab 贵几倍。

    为了检查这是否大致准确,我只启用了一个动画 时间,并检查这是否对应于 Chromium 和 Firefox 开发人员工具报告的内容:

    • Chromium:a 花了 40ms 非空闲; Firefox:2 次调用 n.fx.tick
    • Chromium:b 花了 40ms 非空闲时间; Firefox:4 次调用 n.fx.tick
    • Chromium:c 花了 130 毫秒非空闲; Firefox:36 次调用 n.fx.tick

    这确实大致准确,但不完全准确。

    这对您的应用程序是否足够有用?我不知道。也许,也许不是……



    测试 HTML:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>Animations test</title>
            <style>
                div { width: 200px; height: 100px; position: relative; color: #fff; }
                #test_a { background-color: green; }
                #test_b { background-color: red; }
                #test_c { background-color: blue; }
            </style>
        </head>
    
        <body>
            <div id="test_a"></div>
            <div id="test_b"></div>
            <div id="test_c"></div>
    
            <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
            <script src="anim.js"></script>
        </body>
    </html>
    

    在 CoffeeScript 中测试 JS:

    go = ->
        a = b = c = 0
    
        log = (n, t) ->
            eval "u = #{n}"
            str = "#{n}: #{u} updates; #{parseInt u / t, 10} upd/s"
            $("#test_#{n}").html str
            console.log str
    
        $('#test_a').animate {left: '500px'},
            duration: 500
            step: -> a += 1
            complete: -> log 'a', .5
    
        $('#test_b').animate {top: '100px', left: '100px', opacity: 0.3, width: '500px'},
            duration: 200
            step: -> b += 1
            complete: -> log 'b', 2
    
        $('#test_c').animate {left: '500px', top: '300px', opacity: .75, height: '50px', width: '400px'},
            duration: 3000
            step: -> c += 1
            complete: -> log 'c', 3
    
    $(document).ready -> setTimeout go, 500
    

    为了方便而编译相同的JS:

    // Generated by CoffeeScript 1.7.1
    (function() {
      var go;
    
      go = function() {
        var a, b, c, log;
        a = b = c = 0;
        log = function(n, t) {
          var str;
          eval("u = " + n);
          str = "" + n + ": " + u + " updates; " + (parseInt(u / t, 10)) + " upd/s";
          $("#test_" + n).html(str);
          return console.log(str);
        };
        $('#test_a').animate({
          left: '500px'
        }, {
          duration: 500,
          step: function() {
            return a += 1;
          },
          complete: function() {
            return log('a', .5);
          }
        });
        return;
        $('#test_b').animate({
          top: '100px',
          left: '100px',
          opacity: 0.3,
          width: '500px'
        }, {
          duration: 200,
          step: function() {
            return b += 1;
          },
          complete: function() {
            return log('b', 2);
          }
        });
        return $('#test_c').animate({
          left: '500px',
          top: '300px',
          opacity: .75,
          height: '50px',
          width: '400px'
        }, {
          duration: 3000,
          step: function() {
            return c += 1;
          },
          complete: function() {
            return log('c', 3);
          }
        });
      };
    
      $(document).ready(function() {
        return setTimeout(go, 500);
      });
    
    }).call(this);
    

    【讨论】:

      【解决方案4】:

      您可以尝试在每个 jQuery 动画开始时运行 console.profile() 实例,然后一次禁用一个动画以进行调试。

      据我所知,您无法分析 CSS 动画。只有开始和结束值可以通过 JavaScript 访问。

      function AnimateRotate(elem, angle, dur) {
        var $elem = $(elem);
      
        // we use a pseudo object for the animation
        // (starts from `0` to `angle`), you can name it as you want
        $({
          deg: 0
        }).animate({
          deg: angle
        }, {
          duration: dur,
          step: function(now) {
            // in the step-callback (that is fired each step of the animation),
            // you can use the `now` paramter which contains the current
            // animation-position (`0` up to `angle`)
            $elem.css({
              transform: 'rotate(' + now + 'deg)'
            });
          }
        });
      }
      
      $('#1').click(function() {
        console.profile('Animation #1');
        $(this).animate({
          'height': '100px',
          'width': '100px'
        }, function() {
          console.profileEnd('Animation #1');
        });
      });
      
      $('#2').click(function() {
        console.profile('Animation #2');
        AnimateRotate(this, 3000, 400);
        $(this).animate({
          'height': '300px',
          'width': '300px'
        }, function() {
          console.profileEnd('Animation #2');
        });
      });
      div {
        height: 10px;
        width: 10px;
        background-color: red;
        transform-origin: 60% 100%;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div id="1"></div>
      <br>
      <div id="2"></div>

      【讨论】:

        猜你喜欢
        • 2019-01-29
        • 2020-10-13
        • 1970-01-01
        • 2017-01-24
        • 2016-01-27
        • 2022-01-06
        • 2019-10-01
        • 2016-06-08
        • 1970-01-01
        相关资源
        最近更新 更多