Simple demo of requestAnimationFrame.
Use CSS keyframe animation or CSS transitions and transforms so that the browser can optimize painting/compositing.
Use requestAnimationFrame
for JS-based animation control.
Further, Paul Irish suggests …
Avoid changing inline styles on every frame (jQuery animate()-style) if you can, declarative animations in CSS can be optimized by the browser way more.
Use CSS transforms instead of absolute positioning will typically provide better FPS by way of smaller paint times and smoother animation.
Use Timeline Frame’s mode to investigate what is slowing down your behavior.
Lastly …
“Show Paint Rects” and “Render Composited Layer Borders” are good pro-moves to verify where your element is being rendered.
<!DOCTYPE html>
<meta charset="utf-8">
<script src="//jashkenas.github.io/coffee-script/extras/coffee-script.js"></script>
<body>
<svg>
<rect width="960" height="500" fill="none" stroke="#777" />
<circle cx="480" cy="20" r="20" fill="steelblue"/>
</svg>
<script type="text/coffeescript">
min = 20 # min y-position
max = 480 # max y-position
pos = 20 # initial y-position
dir = 1 # initial direction
fps = 60 # frames per second
speed = 5 # number of pixels to move
delay = 1000 / fps
paused = false
ball = document.querySelector 'circle'
position = (y) =>
ball.cy.baseVal.value += y if y
ball.cy.baseVal.value
move = ->
dir *= -1 if (position() > max) or (position() < min)
position dir * speed
draw = ->
move()
setTimeout (-> window.requestAnimationFrame draw), delay
draw() # use runFor(secs) to run animation for specified time
run = ->
move()
return if paused
window.requestAnimationFrame run
runFor = (secs=2) ->
setTimeout (-> paused = true), secs * 1000
run()
</script>