为了个人教育,我正在尝试用 JavaScript/HTML 构建 Pong 实现。
我一直在阅读rendering performance ,但是当我把这个理论应用到实践中时,似乎还不够。
根据我的理解,requestAnimationFrame 应该为我提供流畅稳定的 60 fps 动画,因为我的逻辑和后续渲染可以在 16 毫秒的时间范围内完成。在这种情况下,每次迭代需要 1 - 2 毫秒,但我看到帧速率在 45 fps 和 75 fps 之间跳跃,偶尔会产生“长帧”。
我在 Mac Mini(2012 年末)的 OS X 10.12 上运行 Chrome。
我尝试过使用 Canvas ,尝试过 CSS 动画方法,还尝试过顶部/左侧方法。我尝试过 Safari,也尝试过隐身模式。然而,卡顿仍然存在。
我错过了什么?
作为引用,这是我的脚本(在 CoffeeScript 中):
class window.PongGame
@launch: ->
window.pong = new PongGame()
pong.start()
constructor: ->
@ball_size = 32
@width = 640
@height = 480
@y = @height / 2
@x = 0
@yVel = 3
@xVel = 3
@ball = document.getElementById("pong_ball")
start: ->
requestAnimationFrame => @new_frame()
new_frame: ->
@handle_collisions()
@move_ball()
@animate()
requestAnimationFrame => @new_frame()
handle_collisions: ->
if (0 <= @x <= @width - @ball_size) is false
@xVel = -@xVel
if (0 < @y < @height - @ball_size) is false
@yVel = -@yVel
move_ball: ->
@x += @xVel
@y += @yVel
animate: ->
@ball.setAttribute("style", "transform: translate(#{@x}px, #{@y}px); width: #{@ball_size}px; height: #{@ball_size}px")
Jsfiddle:https://jsfiddle.net/nielsbuus/ptLk3ma0/2/
更新
我在较旧的 MacBook Pro (2011) 上测试了我的代码,帧速率几乎稳定 - 比我的 Mac Mini 更接近固定的 60 fps。
最佳答案
关于浏览器中的 requestAnimationFrame
性能,有几个有趣的事实需要记住...
使用探查器会影响结果。我正在开发一个基于 Three.js 的 WebGL 项目,其中集成的 FPS 计数器报告相对稳定的 60fps。但是,如果我激活 Chrome 的时间线工具并测量帧渲染时间,时间线显示应用程序每秒丢掉 4-6 帧,即使渲染循环中根本没有代码也是如此。
浏览器管理许多其他事件,它们会影响动画性能。在使用大量内存的长期运行的 Firefox 实例中运行我的应用程序总是比在新实例中运行它的性能更差。在 Chrome 的另一个选项卡中流式传输视频会将我的应用程序的帧速率降低到 30 FPS(可能是因为它们都在争夺 GPU 时间)。垃圾收集会消耗帧预算中的大量时间,从而最大限度地减少对象分配,并且 GC 对于具有大量动画的复杂应用程序来说是一个重要问题。
特别是,当您使用Chrome的时间轴工具时,请务必启用JS Profiling,并扩大GPU事件范围。您的代码可能完全在 16.6 毫秒帧预算之内,但在我的系统上,丢帧通常与繁重的 GPU 事件相关。
我的建议?不要将分析器的结果视为现实世界性能的绝对或代表,并接受浏览器动画性能有点像过山车:)。
您也可以考虑使用 FPS counter为 Three.js 开发(但我认为可以在任何地方使用),我认为它比现代浏览器中的重量级分析工具具有更少的扭曲影响。在开发过程中保持其运行可以在您遇到严重的性能问题时提醒您。
关于javascript - 使用 requestAnimationFrame 的 JavaScript 动画帧速率不稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41109313/