use requestAnimationFrame to reduce trigger lag