message: perf(animationFrames): uses fewer Subscription instances
  Leverages a single id variable instead of creating a new child Subscription for each scheduled animation frame. This is important because animation frames are scheduled very rapidly and this helps prevent CPU and GC thrashing.
  related
diff: import { Observable } from '../../Observable';
  -import { Subscription } from '../../Subscription';
  import { TimestampProvider } from '../../types';
  import { performanceTimestampProvider } from '../../scheduler/performanceTimestampProvider';
  import { animationFrameProvider } from '../../scheduler/animationFrameProvider';
  @@ -82,19 +81,23 @@ export function animationFrames(timestampProvider?: TimestampProvider) {
  * @param timestampProvider The timestamp provider to use to create the observable
  */
  function animationFramesFactory(timestampProvider?: TimestampProvider) {
  - const { schedule } = animationFrameProvider;
  return new Observable<{ timestamp: number; elapsed: number }>((subscriber) => {
  - const subscription = new Subscription();
  // If no timestamp provider is specified, use performance.now() - as it
  // will return timestamps 'compatible' with those passed to the run
  // callback and won't be affected by NTP adjustments, etc.
  const provider = timestampProvider || performanceTimestampProvider;
  +
  // Capture the start time upon subscription, as the run callback can remain
  // queued for a considerable period of time and the elapsed time should
  // represent the time elapsed since subscription - not the time since the
  // first rendered animation frame.
  const start = provider.now();
  - const run = (timestamp: DOMHighResTimeStamp | number) => {
  +
  + let id = 0;
  + const run = () => {
  + if (!subscriber.closed) {
  + id = animationFrameProvider.requestAnimationFrame((timestamp: DOMHighResTimeStamp | number) => {
  + id = 0;
  // Use the provider's timestamp to calculate the elapsed time. Note that
  // this means - if the caller hasn't passed a provider - that
  // performance.now() will be used instead of the timestamp that was
  @@ -107,12 +110,18 @@ function animationFramesFactory(timestampProvider?: TimestampProvider) {
  timestamp: timestampProvider ? now : timestamp,
  elapsed: now - start,
  });
  - if (!subscriber.closed) {
  - subscription.add(schedule(run));
  + run();
  + });
  + }
  + };
  +
  + run();
  +
  + return () => {
  + if (id) {
  + animationFrameProvider.cancelAnimationFrame(id);
  }
  };
  - subscription.add(schedule(run));
  - return subscription;
  });
  }
  