Use requestAnimationFrame instead of setTimeout